javascript - React 组件无法同步由动态 ReactDOM.render 创建的 props

标签 javascript reactjs

当我使用React+Redux+Immutable时,我遇到一个问题:动态创建的组件,当props改变时,组件不会重新渲染。 这是 React 的 bug 吗?

我删除了业务代码,这里只保留React代码:http://codepen.io/anon/pen/GoMOEZ

或以下:

import React from 'react'
import ReactDOM from 'react-dom'

class A extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'tom'
        }
    }

    dynamic() {
        ReactDOM.render(<B name={this.state.name} changeName={this.changeName.bind(this)} type={false}/>, document.getElementById('box'))
    }

    changeName() {
        this.setState({
            name: 'tom->' + Date.now()
        });
    }

    render() {
        return <div>
            top name: {this.state.name}
            <B name={this.state.name} changeName={this.changeName.bind(this)} type={true}/>
            <div id="box"></div>
            <button onClick={this.dynamic.bind(this)}>dynamic add component</button>
        </div>
    }
}

class B extends React.Component {
    render() {
        return <div>
            {this.props.type ? '(A)as sub component' : '(B)create by ReactDOM.render'}
            - name:【{this.props.name}】
            <button onClick={this.props.changeName}>change name</button>
        </div>
    }
}

ReactDOM.render(
    <A/>,
    document.getElementById('example')
);

最佳答案

这不是一个错误,它只是不是做你想做的事情的 React 方式。每次调用A.render将覆盖 <div id="box">...</div>删除 A.dynamic 添加的元素.

更惯用的方法是添加一些标志,将其设置在onClick中处理程序并在 A.render 中使用它决定是否 <div id="box">应该为空或不为空。

在codepen上查看编辑后的代码:http://codepen.io/anon/pen/obGodN

相关部分在这里:

class A extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        name: 'tom',
        showB: false // new flag
      }
    }

    changeName() {
        this.setState({
          name: 'tom->' + Date.now()
        });
    }

    // changing flag on button click
    showB() {
        this.setState({showB: true})
    }

    render() {
        // `dynamic` will contain component B after button is clicked 
        var dynamic;
        if(this.state.showB) {
          dynamic = <B
            name = {this.state.name}
            changeName = {this.changeName.bind(this)}
            type = {false} />
        }
        return <div>
          top name: {this.state.name}
          <B name = {this.state.name}
             changeName = {this.changeName.bind(this)}
             type = {true}/>
          <div>{dynamic}</div>
          <button onClick = {this.showB.bind(this)}>
            dynamic add component
          </button>
        </div>
      }
    }

更新
您仍然可以使用您的方法,但需要手动更新动态创建的组件。

例如您可以在 changeName 中手动重新渲染它功能。

  changeName() {
    this.setState({
      name: 'tom->' + Date.now()
    }, this.dynamic.bind(this));
  }

请注意,this.dynamic作为第二个参数传递给 this.setState这确保了当状态真正更新时它会被调用。只需添加 this.dynamic()之后this.setState({...})将使用尚未更新的状态。

代码笔在这里:http://codepen.io/anon/pen/EPwovV

关于javascript - React 组件无法同步由动态 ReactDOM.render 创建的 props,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34824464/

相关文章:

javascript - 使用react-app-rewired将webpack配置添加到react-create-app

javascript - 在 React 中切换 css 类

javascript - 有没有办法在Javascript中触发 "Ctrl+Shift+P"事件?

javascript - polymer-webpack-loader : how to import & transpile Polymer . html模板

CSS 模块和 ReactJS : Parent and child CSS classes in different components

css - 来自 css 的样式 react-bootstrap 按钮

reactjs - 如何使用Spring Boot Web服务器在浏览器中显示我的React生产版本?

javascript - 向上/向下箭头点击 如果点击太快选择太多

javascript - 如何使用 javascript 添加 css 属性?

javascript - 使用 fetch 和 ajax 获取 json 会产生不同的响应