简体   繁体   中英

How to setState a class object in React?

I have an array of objects inside my class that I am modifying and only when a keypress happens do I want to render this object visually.

class Example extends React.Component {
    constructor(props) { 
       super(props); 
       this.myArr = []; // this is an array of objects 
    }

    render() {  
       return (
        ???
       );
    }
}

Now I modify the contents of this.myArr in many different methods. And only when I'm ready (on a keypress or some other event) do I want to render it.

Now in my render() should I have a reference to this.myArr and then use this.forceUpdate() when I want to force a re-render.

Or should I move myArr into this.state.myArr , and modify this.state.myArr in my methods and when I am ready to display it, in my render() reference to this.state.myArr , and somehow force a rerender with this.setState(myArr: this.state.myArr);

***Second Update - I think this may be what you want. Obviously, you'll need to add a lot of logic for your mouse click events. It should point you in the right direction though.

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.myArr = [];

    this.state = {
      myArr: [{ width: 10 }, { width: 20 }], // header widths
    };
  }

  // call changeHeaders when needed
  // it will update state, which will cause a re-render
  changeHeaders = (column, newWidth) => {
    const newArr = [...this.state.myArr];

    if (newArr[column]) {
      newArr[column].width = newWidth;
    }

    this.setState({ myArr: newArr });
  }

  renderArray = () => {
    return this.state.myArr.map(({ width }) => <div>{width}</div>);
  }

  render() {
    return (
      <div>
        {this.renderArray()}
      </div>
    );
  }
}

Either way would work but I think its better practice to use this.state to hold your array and use this.setState() to force a re-render and call the this.setState within your keypress event callback

Here is how you update your array value - Correct modification of state arrays in ReactJS

There's a very good explanation why you should avoid using this.forceUpdate() in here answered by Chris.

In this case you should use state. State is intended to be used for any data that affect how your component looks. Remember that you may not modify your state directly, it's an antipattern. Instead, you should create a copy of the array and update the state with that modified copy. Like so:

class Example extends React.Component {
  constructor(props) { 
    super(props); 
    this.state = {myArr: []}; // this is an array of objects 
  }

  mutateArraySomehow() {
    const nextArr = [...this.state.myArr];
    nextArr.push('heyyoooo');
    this.setState({myArr: nextArr});
  }

  render() {  
    return (
      ???
    );
  }
}

This is how i would have done it

class Example extends React.Component {
   constructor(props) { 
      super(props);
      this.state = {
       myArr: [],
       display: false
      }
   }

   render() {
      if(this.state.display) {
       return (
          <MyComponent onKeyPress=(ev=>{
              this.setState({display: true})
          })
         />
       );
      } else {
       return (<div></div>)
      }
   }
}

When there is a modification to the array elements, you need to do a setState of status to true.This would perform the conditional rendering and will display the modified array.

class Example extends React.Component {
  constructor(props) { 
    super(props); 
    this.state = {
      myArr = []; // this is an array of objects 
      status:false
    }
  }

  modifyArr = () => {
    //some array modifications
    this.setState({status:true})
  }

  render() {  
    return (
      {this.state.status ? null : (<div>`Display your array here`</div>)}
    );
  }
}

In short, define state inside class like:

state: {
   firstName: String
} = {
   firstName: ''
}

And inside render function you would do this:

this.setState({ firstName: 'Junior' })

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