2017-02-07 3 views
0

Скажем, у меня был простой 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> 

Однако при этом оказывается, любой обновление в одно из двух полей обновляет оба из них (из-за сокращения, допускающего только одно состояние).

Что такое канонический способ решения этой проблемы?

+1

Не ставьте состояние, которое не должно использоваться совместно с Redux. Redux следует использовать для состояния, о котором должны знать другие части приложения. Если вы должны это сделать, сопоставьте уникальный идентификатор с каждым экземпляром компонента (иначе это переходное состояние). –

ответ

0

Вот один из подходов Авраама и пример того, что Дэн прокомментировал. Check out this jsBin демонстрирует концепцию компонента (здесь это SimpleInput), сохраняя собственное внутреннее состояние (например, заполнитель по умолчанию), все еще взаимодействуя с контейнером (слушая onChange). Хотя в примере не используется Redux (для простоты создания демонстрации) вы можете легко заменить handleChange дескрипторами действий.

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

Один из моих случаев использования был поиск адресов с входом управляющего его значение внутри (не перевождите) и кнопкой поиска, излучающее значение входа через OnClick = {this.props.onSave} и в Контейнер, управляющий всеми побочными эффектами/редукционными действиями и т. Д.

Наконец, в вашем демо-коде вы без необходимости переопределяете SimpleInput, который выглядит как запах кода. Надеюсь, это поможет.

Смежные вопросы