2017-02-07 2 views
0

sagen, dass ich wie so eine einfache inputfieldcomponent hatte:Mehrere Instanzen einer Komponente sollte nicht Staat teilen

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

ich dann zwei Instanzen machen:

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

Wenn dies jedoch gemacht wird, jede Die Aktualisierung auf eines der beiden Felder aktualisiert beide (aufgrund von redux nur für einen einzelnen Zustand).

Was ist der kanonische Weg, um dieses Problem anzugehen?

+1

Legen Sie keinen Status fest, der nicht in Redux geteilt werden soll. Redux sollte für den Status verwendet werden, über den andere Teile der App informiert werden müssen. Wenn Sie dies tun müssen, ordnen Sie jeder Instanz der Komponente eine eindeutige Kennung zu (auch als Übergangszustand bezeichnet). –

Antwort

0

Hier ist eine Annäherung Abraham und geben ein Beispiel zu dem, was Dan kommentierte. Check out this jsBin demonstriert das Konzept einer Komponente (hier ist es SimpleInput) seinen eigenen internen Zustand zu behalten (wie ein Standardplatzhalter), während noch mit einem Container interagiert (onChange zuhören). Während das Beispiel keinen Redux verwendet (zur Vereinfachung der Erstellung der Demo), könnten Sie leicht onChange-Handles durch Action-Dispatcher ersetzen.

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

Einer meiner Anwendungsfälle war eine Adresssuche mit einem Eingabewert es ist intern Verwaltung (kein redux) und eine Lookup-Taste, um den Wert des Eingangs über onClick = {} this.props.onSave emittiert und in der Container behandelt alle Nebenwirkungen/Redux-Aktionen usw.

Schließlich in Ihrem Demo-Code, Sie unnötigerweise SimpleInput, die wie ein Code-Geruch aussieht. Ich hoffe, das hilft.

Verwandte Themen