简体   繁体   中英

React setState() after fetch not rerendering

I am fetching data in componentDidMount() (I am getting them in the form I want) and I want to save them in the component state with this.setState . The state is not changing.

  • I console log that I am getting to the point where setState is called - there are conditions
  • I tried const that = this

The component is not re-rendering and state is not changing and I would like to know why.

My code:

export class Offers extends Component {
    constructor(props) {
        super(props);
        this.renderOffer = this.renderOffer.bind(this);
        this.state = {
        ...
        };
    }
    componentWillMount() {
        this.setState(() => ({
            offer: {},
            isLoading: true,
            isMyOffer: false,

            ...
        }));
    }

    componentDidMount() {
        console.log('MOUNTED');
        const { profile } = this.props;
        if (profile) {
            this.setState(() => ({
                isLoading: false
            }));
        }
        if (profile && profile._id) {
            this.setState(() => ({
                isMyOffer: true,
                ...
            }));

            fetch(`/api/offers-by/${profile._id}`,{
                method: 'GET'
            })
           .then(response => response.json())
           .then(offers => {
               if(!offers || !offers.length) {
                   this.setState(() => ({
                   isLoading: false
                  })
                  );
              } else {
                  console.log('ELSE', offers[0]._id); // getting proper data
                  console.log('THIS', this) // getting this object 
                  const offerData = offers[0]
                  this.setState(() => ({
                      offer: offerData,
                      isLoading: false
                  })) //  then
              }}) // fetch
              console.log('STATE', this.state)
          }
          console.log('STATE', this.state)
    }

setState has a callback method as the second argument.You should use that after the initial setState.This works because setState itself is an asynchronous operation.The setState() method does not immediately update the state of the component but rather if there are multiple setStates, they will be batched together into one setState call.

this.setState(() => ({
            isLoading: false
        }),() =>{
   /// You can call setState again here and again use callback and  call fetch and invoke setState again..
});

Ideally you could refactor some of your setStates into a single setState call.Start with an empty object and add properties to your object based on conditons.

const updatedState ={}
if(loading){
 updatedState.loading = false
}
if(profile &&..){
 updatedState.someProperty = value.
}

this.setState(updatedObject,()=> {//code for fetch..
}) // Using the object form since you don't seem to be in need of previous State.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM