组件的多个实例不应共享状态

时间:2017-02-07 00:05:51

标签: reactjs redux react-redux

假设我有一个像这样的简单inputfieldcomponent:

import React, {PropTypes, PureComponent} from 'react';
import {render} from 'react-dom';
import {connect} from 'react-redux';
import updateInput from '../../actions/inputActions';

require('./SimpleInput.sass');

export class SimpleInput extends PureComponent {
    constructor(props, context) {
         super(props, context);
    }

    handleChange (event) {
        this.props.updateField(event.target.value);
    }

    renderField () {
        return (
            <input type="text" value={this.props.value || ''} onChange={this::this.handleChange} placeholder={this.props.initial_value}/>
        )
    }

    render () {
        return(
            <span>
                {this.renderField()}
            </span>
        )
    }
}

const mapStateToProps = (state) => {
    return {value: state.value.value}
}

const mapDispatchToProps = (dispatch) => {
    return {
        updateInput: (value) => dispatch(updateInput(value))
    };
};

AddressInput.propTypes = {
    initial_value: PropTypes.string
};

AddressInput.defaultProps = {
    initial_value: "What's the value?"
};

export default connect(mapStateToProps, mapDispatchToProps)(SimpleInput);

然后我渲染两个实例:

</SimpleInput initial_value='blah'/>
</SimpleInput>

但是,渲染时,对两个字段之一的任何更新都会更新它们(由于redux只允许单个状态)。

解决此问题的规范方法是什么?

1 个答案:

答案 0 :(得分:0)

以下是亚伯拉罕的一个方法,并举例说明丹所评论的内容。 Check out this jsBin演示组件的概念(此处为SimpleInput)保持其自身的内部状态(例如默认占位符),同时仍与Container交互(侦听onChange)。虽然该示例不使用Redux(为了简化创建演示),您可以轻松地使用操作调度程序替换onChange句柄。

class SimpleInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      defaultPlaceholder: 'Default Placeholder'
    }
  }

  render() {
    return (
      <input 
        value={this.props.value} 
        placeholder={this.props.placeholder || this.state.defaultPlaceholder}
        onChange={this.props.onChange || ()=>{} }
      />
    )
  }

}

class SimpleInputContainer extends React.Component {
  constructor(props) {
    super(props);
    this.changeInput1 = this.changeInput1.bind(this);
    this.changeInput2 = this.changeInput2.bind(this);
    this.state = {
      input1: 'foo',
      input2: 'bar',
    }
  }

  changeInput1(e) {
    this.setState({
      input1: e.target.value
    })
    console.log(this.state);
  }

  changeInput2(e) {
    this.setState({
      input2: e.target.value
    })
  }

  render() {
    return (
      <div>
        <SimpleInput value={this.state.input1} onChange={this.changeInput1} />
        <br />
        <SimpleInput value={this.state.input2} onChange={this.changeInput2} />
        <br />
        <SimpleInput />
        <br />
        <SimpleInput placeholder={'Explicit Placeholder'} />
      </div>
      );
  }
}

ReactDOM.render(<SimpleInputContainer />, document.getElementById('app'));

我的一个使用案例是一个地址查找,一个输入在内部管理它的值(没有redux),一个查找按钮通过onClick = {this.props.onSave}发出输入值,并在Container处理所有方面效果/减少行动等。

最后在您的演示代码中,您不必要地重新渲染SimpleInput,这看起来像代码味道。希望有所帮助。