javascript - ReactJS:通过 props 从父级改变子级状态

标签 javascript reactjs

免责声明:我看过Reactjs: how to modify child state or props from parent?并且不相信答案符合我的问题。

所以我有一个可重用的、有状态的对话组件,它根据其状态呈现不同的 DOM。我还必须能够控制从父级渲染哪个 DOM。

TL;DR - 我应该如何从父组件改变子组件的状态,如果有的话,还有哪些其他选项?

child :

export default class Conversation extends Component {
  constructor(props) {
    super(props);
    
    this.state = {
      newConversation: props.showNewConversation
    };
  }
  
  render() {
   if (!this.state.newConversation) {
    return (
      <div>Current Conversation</div>
    );
   } return (
      <div>New Conversation</div>
    );
  }
}

现在我需要在不同的地方渲染这个组件,但是我需要根据父组件渲染适当的 DOM,即从导航栏你可以创建一个新的对话,从用户页面你可以直接进入你的对话和他们在一起,这样我就可以控制何时通过它的 Prop 调用 child 。

通过 prop 调用子进程并设置状态:

<Conversation
  showNewConversation={this.state.isConversationShown === true}
/>

这目前正在工作,但我被告知这是 React 中的一个非常糟糕的实践,我的问题实际上是为什么这被认为是不好的实践,以及一个好的实践解决方案是什么样的。

最佳答案

在 React 中,一般的最佳实践是如果可能的话,使尽可能多的组件“无状态”。通常,如果您不加载异步数据或接受用户输入,则不需要状态。

在此示例中,主要问题如下:如果父渲染

<Conversation newConversation={true} />

稍后将其重新渲染为

<Conversation newConversation={false} />

然后子级将不会按预期渲染,因为 React 将“更新”子级对话(重新渲染),但不会再次调用构造函数。因为您只将 props 转移到构造函数中的状态,所以子级永远不会改变。

大多数组件应该仅根据其属性进行渲染。您的 child 可以适应以下情况:

export default class Conversation extends Component {
  constructor(props) {
    super(props);
  }

  render() {
   if (!this.props.newConversation) {
    return (
      <div>Current Conversation</div>
    );
   } return (
      <div>New Conversation</div>
    );
  }
}

在这里,父级的更新将允许子级正确地重新渲染,因为您直接引用子级的 render() 函数中的 props。

如果您有更多有关正在呈现的对话的数据,那么您应该将所有数据作为 Prop 传递。即

<Conversation conversationData={{name: 'abc', new: false}} />

然后Conversation组件就可以直接在render()方法中访问props了。

如果您绝对必须更改状态,那么它应该采用父级更改 props 的形式:

export default class Conversation extends Component {
  constructor(props) {
    super(props);

    this.state = {
      newConversation: props.showNewConversation
    };
  }

  // Response to change
  componentWillReceiveProps(nextProps){
      this.setState({newConversation: this.props.showNewConversation});

  }

  render() {
   if (!this.state.newConversation) {
    return (
      <div>Current Conversation</div>
    );
   } return (
      <div>New Conversation</div>
    );
  }
}

关于javascript - ReactJS:通过 props 从父级改变子级状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38135445/

相关文章:

javascript - 使用 React JS 实现状态码为 404 时的 catch

javascript - 与 InAppBrowser 在 Phonegap 中等效的 window.close

reactjs - ReactJS 中的高阶组件 - 从数据组件扩展功能

reactjs - 如何在 ReactJS 中更改可重用组件的背景颜色?

javascript - 我怎样才能停止 webpack-dev-server

javascript - 检查字符串以查看其是否为空

javascript window.var_name 与窗口 ['var_name' ]

reactjs - 如何修复在退格键上不更新的 React 搜索过滤器

Javascript - 简单的 Jquery 设置 CSS 问题

reactjs - 在react-router中路由嵌套url