【问题标题】:React setState twice renders stateReact setState 两次渲染状态
【发布时间】:2019-01-07 20:52:39
【问题描述】:

当我使用 setState 进行交易时,它会转两次。首先返回数据失败,然后返回数据就绪。控制台先返回 false,然后返回 true。我只想在控制台中返回 true。

export default class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: false,
            data: []
        };
    }
    componentDidMount() {
        fetch("https://reqres.in/api/users?page=2")
            .then(res => res.json())
            .then(result => {
                this.setState({
                    data: result.data,
                    loading: true
                });
            });
    }
    render() {
        const { loading } = this.state;
        console.log(loading);
        const dataReady = <div>Data Ready </div>;

        const DataFail = <div>Data Fail </div>;
        return <div>{loading === true ? dataReady : DataFail}</div>;
    }
}

示例: https://codesandbox.io/s/kopz8wrl7o

【问题讨论】:

  • 你的意思是你只想返回true?
  • 是只返回真。
  • 你的意思是这样? codesandbox.io/s/rj8po7jzrq
  • 您不能只在控制台中返回 true。因为加载的初始状态为假。所以这将在初始渲染之前显示在控制台中。之后,That 将变为 true。
  • 你应该查看生命周期函数 shouldComponentUpdate()

标签: javascript reactjs fetch fetch-api


【解决方案1】:

您只需反转与加载相关的布尔值。最初应将其设置为true,然后在加载数据时设置为false。

工作示例:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            error: false,
            data: []
        };
    }
    componentDidMount() {
        fetch("https://reqres.in/api/users?page=2")
            .then(res => res.json())
            .then(result => {
                this.setState({
                    data: result.data,
                    loading: false
                });
            })
            .catch(error =>{
                this.setState({ error: true });
            });
    }
    render() {
        const { loading, error } = this.state;
        !loading && console.log(true)

        return <div>{!loading && <div>Data Ready </div>}
          {error && <div>Data Error :( </div>}
        </div>;
    }
}
    
ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.1.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.1.1/umd/react-dom.production.min.js"></script>
<div id='root'/>

【讨论】:

  • 我想我无法准确解释这个问题。我只想在控制台返回true,我的初始值为false。
  • 您只想在加载数据时返回 true ?
  • 好了,现在你的组件在数据加载时记录true
  • 我需要在render下执行控制台进程。
  • 好吧,我不知道这是必要的,但你去吧。渲染任何已完成加载的条件只是!loading
【解决方案2】:

您的数据发生了变化,这就是您收到两条消息的原因:

你需要做决定,你要做什么? 如果您不想更改状态,可以使用shouldComponentUpdate,或者您可以跳过 1 条控制台消息

【讨论】:

  • 如何在不使用 componentDidMount 的情况下使用 shouldComponentUpdate ?
  • 你可以保留componentDidMount,只添加shouldComponentUpdate
【解决方案3】:

这是由于 React 的生命周期以及您最初将 state.loading 属性设置为 false 的事实。 https://reactjs.org/docs/react-component.html

首先是初始渲染,然后调用 componentDidMount 及其 setState。您可能希望不定义加载,然后在渲染方法中检查其是否已定义,然后再检查其值。

【讨论】:

    猜你喜欢
    • 2021-11-07
    • 2017-07-23
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2022-11-26
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多