React - 处理通过迭代通过数组呈现的状态的输入更改

时间:2017-03-28 09:39:10

标签: javascript reactjs

这是我的代码......

    class Module extends Component {
        constructor() {
            super()

            this.state = {
                inputs: [
                    { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' },
                    { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' },
                    { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' },
                ]
            }

            this.handleInputChange = this.handleInputChange.bind(this)
            this.saveModule = this.saveModule.bind(this)
        }

        handleInputChange(event) {
            this.setState ({
                [event.target.name]: event.target.value
            })
        }

        renderInput = (input) => {
            return(
                <div key={ input.id }>
                    <input
                        type={ input.type }
                        name={ input.name }
                        placeholder={ input.placeholder }
                        onBlur={ this.saveModule }
                        value={ input.value }
                        onChange={ this.handleInputChange }
                    />
                </div>
            )
        }

        render() {
            return (
                <div>
                    { this.state.inputs.map(this.renderInput) }
                </div>
            )
        }
    }

    export default Module

如何以这种方式处理从状态呈现的值的输入变化?! 如果我有{this.state.input.value}它完全正常,一旦我像这样重构它,setState似乎不再达到它。

有什么想法吗? :)

提前多多感谢!

2 个答案:

答案 0 :(得分:2)

由于您希望直接在input array创建input元素的位置进行更改,因此您需要在onChange方法中进行更改。使用任何唯一属性(如名称或索引)来标识已更改的元素,迭代input array查找该输入元素,然后更新该元素的值。更新输入数组中的值后,也更新状态输入数组,当UI重新呈现组件时,值将自动反映在react中。

检查工作代码:

&#13;
&#13;
class Module extends React.Component {
        constructor() {
            super()

            this.state = {
                inputs: [
                    { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' },
                    { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' },
                    { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' },
                ]
            }

            this.handleInputChange = this.handleInputChange.bind(this)
        }

        handleInputChange(event) {
            let inputs = this.state.inputs.slice();
            for(let i in inputs){
                if(inputs[i].name == event.target.name){
                    inputs[i].value = event.target.value;
                    this.setState ({inputs});
                    break;
                }
            }
        }

        renderInput = (input, i) => {
            return(
                <div key={ input.id }>
                    <input
                        type={ input.type }
                        name={ input.name }
                        placeholder={ input.placeholder }
                        onBlur={ this.saveModule }
                        value={ input.value }
                        onChange={ this.handleInputChange }
                    />
                </div>
            )
        }

        render() {
            return (
                <div>
                    { this.state.inputs.map(this.renderInput) }
                </div>
            )
        }
    }


ReactDOM.render(<Module/>, document.getElementById('app'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您必须先通过创建新状态来设置状态。

由于this.state是不可变的,因此只需使用spread operatorObject.assign修改旧状态即可创建新状态。

This video是如何以不可变的方式更改javascript对象的一个​​很好的参考。还有一个专门用于创建和修改有效名为immutable.js的不可变对象的库。

Refer to this how to use immutable.js with react setState

(此代码已经过测试)

class Module extends Component {
    constructor() {
        super()

        this.state = {
            inputs: [
                { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' },
                { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' },
                { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' },
            ]
        }

        this.handleInputChange = this.handleInputChange.bind(this)
        this.saveModule = this.saveModule.bind(this)
    }

    // change this to an arrow function
    handleInputChange = (event) =>  {
        const name = event.target.name;
        const value = event.target.value;
        const oldInputState = this.state.inputs.find(i => i.name === name);
        // use the spread operator or Object.assign to create a brand new state object
        this.setState({
            ...,
            this.state, // copy everything from the old state
            // expect change the `inputs` value
            {inputs: [ // create a brand new array
                ...this.state.inputs.filter(i => i.name !== name),
                {...oldInputState, value} // replace old value with the new value
                // refer to that video I included, it's a great explanation
            ]}
        });
    }

    renderInput = (input) => {
        return(
            <div key={ input.id }>
                <input
                    type={ input.type }
                    name={ input.name }
                    placeholder={ input.placeholder }
                    onBlur={ this.saveModule }
                    value={ input.value }
                    onChange={ this.handleInputChange }
                />
            </div>
        )
    }

    render() {
        return (
            <div>
                { this.state.inputs.map(this.renderInput) }
            </div>
        )
    }
}

export default Module
祝你好运!