如何在React中setState一个类对象?

5

我在类中有一个对象数组,我正在修改它,只有在按键事件发生时,我才想将此对象可视化呈现。

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

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

现在我用许多不同的方法修改了this.myArr的内容。只有当我准备好(按下某个键或其他事件)时,我才想呈现它。

现在在我的render()中,我应该引用this.myArr,然后在需要强制重新渲染时使用this.forceUpdate()吗?

还是应该将myArr移动到this.state.myArr中,在我的方法中修改this.state.myArr,并在准备显示它时,在我的render()中引用this.state.myArr,并以某种方式使用this.setState(myArr: this.state.myArr);强制重新渲染?

6个回答

3

第二次更新 - 我认为这可能是你想要的。显然,你需要为鼠标点击事件添加许多逻辑。但它应该会指引你朝着正确的方向。

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>
    );
  }
}

keyPressed 可能是某种事件...(不一定是按键事件)。但你的意思是我应该将此事件命名为 bool ... 有趣。 - Shai UI
当然 - 我并没有真正涉及到捕获按键事件。它可以是任何你想要的东西。我假设你在这方面没问题。主要的事情是:你想要将keyPressed布尔值放在状态中,以便你可以切换它的开和关,同时重新渲染你的组件并显示this.myObj。然后,当你想要隐藏它时,你将keyPressed更新为false,组件将重新渲染,而this.myObj将再次被隐藏。总的来说,你应该尽量避免使用forceUpdate()。它很少是必要的,在React中也不是最佳实践,除非不可避免。 - twils0
嗯...其实我不认为这会起作用。我的操作是在网格中更改标题的宽度,当用户使用鼠标更改宽度时。标题的宽度位于this.myArr[columnIndex].width中...因此,当其中一个宽度改变时,需要重新呈现它。 - Shai UI
你这里改变了一下哈哈。我马上更新。等一下。 - twils0
谢谢你的帮助。虽然看起来有点麻烦,但更容易的方法是修改我的类对象并在完成后调用forceUpdate,让渲染使用我的类对象。 - Shai UI
1
@foreyez 你说得对,性能确实很重要。调用setState实际上是异步的(尽管您可能经常不会注意到),并且为了提高性能而进行批处理。React还非常聪明地更新实际内容,特别是如果您使用[PureComponent](https://reactjs.org/docs/react-api.html#reactpurecomponent)。如果您正在寻找可变状态管理库,我建议使用[mobx](https://github.com/mobxjs/mobx)。它将为您改变状态并重新渲染。 - twils0

0
简而言之,在类内部定义state,如下所示:
state: {
   firstName: String
} = {
   firstName: ''
}

render函数内,您将执行以下操作:

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

0
在这种情况下,您应该使用状态。状态旨在用于影响组件外观的任何数据。请记住,您不可以直接修改状态,这是一种反模式。相反,您应该创建数组的副本,并使用该修改后的副本更新状态。像这样:
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 (
      ???
    );
  }
}

0

这是我会做的方式

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>)
      }
   }
}

0
当数组元素发生修改时,您需要将状态设置为true。这将执行条件渲染并显示修改后的数组。
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>)}
    );
  }
}

0

无论哪种方式都可以,但我认为最好的做法是使用this.state来保存你的数组,并使用this.setState()强制重新渲染并在你的keypress事件回调中调用this.setState

以下是如何更新数组值的方法 - ReactJS中正确修改状态数组

这里有一个非常好的解释,为什么你应该避免使用this.forceUpdate(),由Chris在这里回答。


如果我按照你所说的将它放在this.state中,我能否在我的方法中修改this.state.myArr,并使用this.setState(myArr: this.state.myArr)重新渲染它? - Shai UI
是的,您可以覆盖数组值并使用setState更新视图。 - Robert Chan
不,你永远不应该直接修改状态。创建一个数组的副本,以任何你喜欢的方式进行改变,然后使用新数组更新状态。 - Kit Isaev
1
@KitIsaev 正确的。如React文档所述,您不应直接更改状态值。在我的答案中,我列出了一个关于通过setState更新数组值的正确方式的链接,以及一个关于为什么应尽可能避免使用this.forceUpdate的链接。 - Robert Chan
@RobertChan 我猜他没有仔细阅读并打算改变状态。我这么认为是因为他要使用当前状态更新状态 this.setState({myArr: this.state.myArr}),这让我觉得他打算在直接改变状态后使用setState来强制重新渲染。 - Kit Isaev
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接