最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to update state with setState before render - Stack Overflow

programmeradmin2浏览0评论

I'll preface this by stating that I'm a complete beginner at React.js

I've created an example of a project I'm working on where I call an API in componentDidMount() and get an array of objects back, setting it in state. Here's what it looks like:

class App extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        thing: []
    }
}
componentDidMount() {
    // Fake API
    const apiCall = () => ({
      data: "test"
    })

    // Fake call
    const data = apiCall()

    this.setState({
        thing: [
            ...this.state.thing,
            data
        ]
    })
}
render() {
    return (
        <div>
            <h1>{ this.state.thing[0].data }</h1>
        </div>
    )
}

}

I'm aware that setState isn't guaranteed to update when it's used according to the documentation. I also found "forceUpdate()," and the docs recommends using it as little as possible. Nevertheless, I attempted to use it, but to no avail.

I'm able to console.log the new state during the componentDidMount() run and in the render's h1 element, but I'm unable to actually show it in the render since it's rendering an empty state array at first.

My question is: Is there a way to force my state to update before the render is run by my program so that I can see it, and if not, how would I be able to see my new state reflected in the JSX?

I'll preface this by stating that I'm a complete beginner at React.js

I've created an example of a project I'm working on where I call an API in componentDidMount() and get an array of objects back, setting it in state. Here's what it looks like:

class App extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        thing: []
    }
}
componentDidMount() {
    // Fake API
    const apiCall = () => ({
      data: "test"
    })

    // Fake call
    const data = apiCall()

    this.setState({
        thing: [
            ...this.state.thing,
            data
        ]
    })
}
render() {
    return (
        <div>
            <h1>{ this.state.thing[0].data }</h1>
        </div>
    )
}

}

I'm aware that setState isn't guaranteed to update when it's used according to the documentation. I also found "forceUpdate()," and the docs recommends using it as little as possible. Nevertheless, I attempted to use it, but to no avail.

I'm able to console.log the new state during the componentDidMount() run and in the render's h1 element, but I'm unable to actually show it in the render since it's rendering an empty state array at first.

My question is: Is there a way to force my state to update before the render is run by my program so that I can see it, and if not, how would I be able to see my new state reflected in the JSX?

Share Improve this question edited Jul 19, 2022 at 17:12 Jacob Lockett asked Dec 13, 2017 at 18:07 Jacob LockettJacob Lockett 4852 gold badges7 silver badges17 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 10

componentDidMount is called after the initial render and hence, at the time of initial render this.state.thing[0] is undefined and hence it would cause an error, you need to perform a conditional check before using this.state.thing[0].status

componentDidMount() {
    this.setState({
        thing: [
            {
                status: "running",
                test: "testing"
            }
        ]
    });
}

render() {
    return (
        <div>
            {this.state.thing.length > 0? <h1 className="mt-5 mb-5">{ this.state.thing[0].status }</h1>: null
}
            <button className="mt-5" onClick={ this.handleUpdate } value="not running">
                Click to change
            </button>
        </div>
    );
}

To answer your question, yes there is a way to setState before the initial render and that is with componentWillMount. It is the first lifecycle method to be called in React. The lifecycle method componentDidMount is called after the initial render.

However, looking at your code I'm not sure what the use case is for using componentWillMount. Instead of setting state in componentDidMount or componentWillMount, just set a default state in your constructor function. Then you have the state you want on the initial render and can update it on events accordingly, i.e. your button.

constructor(props) {
    super(props);
    this.state = {
        thing: [
            {
                status: "running",
                test: "testing"
            }
        ]
    };
}

Check out the other React lifecycle methods

It sounds like you want componentWillUpdate or shouldComponentUpdate methods..

发布评论

评论列表(0)

  1. 暂无评论