useState不起作用

时间:2019-11-27 14:05:58

标签: reactjs react-native react-hooks

我试图在API调用后使用useState设置一个变量,但是它不起作用。通过reactotron进行调试,他进行了API调用,但是他没有设置变量。

export default function Forecast({ navigation }) {
  const [cityData, setCityData] = useState([]);
  const idNavigation = navigation.state.params.cityData.woeid;

  async function loadCityData(cityID) {
    const response = await api.get(`${cityID}`);
    setCityData([response]);
    console.tron.log(cityData);
  }

  useEffect(() => {
    if (idNavigation) {
      loadCityData(idNavigation);
    }
    return () => {};
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [idNavigation]);

  return <Text>Forecast Weather</Text>;
}

Forecast.propTypes = {
  navigation: PropTypes.shape({
    state: PropTypes.object,
  }).isRequired,
};

3 个答案:

答案 0 :(得分:0)

大多数情况下,React中的设置状态都是异步的,如果您尝试进行控制台操作,则状态更改可能不可见。建议使用钩子执行此操作的方法是检查useEffect中的更新状态:

 async function loadCityData(cityID) {
  const response = await api.get(`${cityID}`);
  setCityData([response]);
}

// Track cityData and log the changes to it
useEffect(() => {
  console.log(cityData);
}, [cityData]);

// Rest of the code
// ...

答案 1 :(得分:0)

嗯,我认为这可能是电抗器或api问题。 只需尝试

const [cityData, setCityData] = useState('foo');

...

return <Text>{JSON.stringify(cityData)}</Text>;

如果您的证书来自reactron,那么您可以看到来自API的响应。

答案 2 :(得分:0)

因为useState是异步函数。

header('Content-Type: application/xml');

$xml = simplexml_load_string($string);

echo "<root>";
foreach ($xml->xpath("//item") as $item){
    echo $item->asXML();
}
echo "</root>";

查看此示例

    setCityData([response]); // asynchronous function so not set the new data to state yet.
    console.tron.log(cityData);// so you get the old data.
const Forecast = ({ idNavigation }) => {
    const [cityData, setCityData] = React.useState([]);
  
    function loadCityData(cityID) {
      setTimeout(() => {
        setCityData([1,2,3,4,5]);
        console.log("this is old data", cityID, cityData); // because useState is asynchronous function
      }, 2000);
    }
  
    React.useEffect(() => {
      if (idNavigation) {
        console.log("load ", idNavigation);
        loadCityData(idNavigation);
      }
    }, [idNavigation]);
    
    React.useEffect(() => {
      if(cityData.length > 0) {
        console.log("this is new data", cityData);
      }
    }, [cityData]); // when cityData changed and component mounted, this function called.
  
    return <div>Forecast Weather</div>;
  }
  
  class App extends React.Component {
    state = {
      id: 1,
    }
    
    componentDidMount() {
      setTimeout(() => {
        this.setState({id: 2});
      }, 2000);
    }
  
    render() {
      return (
        <div>
          <Forecast idNavigation={this.state.id}/>
        </div>
      );
    }
  }
  
  ReactDOM.render( <App / > , document.getElementById('root'));

解决方案

如果您使用类组件,则可以使用<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.2/umd/react-dom.production.min.js"></script> <div id="root"></div>函数的回调。 但是如果您使用功能组件,则不能使用回调。
因此您应该使用setState()来解决此问题。