React:通过按钮添加输入组件并更新其状态

时间:2017-10-29 14:35:52

标签: javascript reactjs

我正在尝试创建一个按钮,将一个新的输入元素添加到页面,然后在我键入时显示其更改。

但是当我输入<Input />中的输入字段时,由于某种原因状态不会改变。 输入字段保持空白。

出于好奇,我删除了添加<Input />组件的按钮,并在页面上使用一个<Input />字段运行它。当我输入其中一个输入字段时,我可以看到我的文字。

似乎当我向页面添加新组件并尝试更改状态时,某些内容已关闭。

我做错了什么?

function Input(props) {
    console.log(props)
    return (
        <div>
            <div><input name="pitchName" value={props.currentValue.pitchName} placeholder="Pitch Name" onChange = {props.updateNewPitch}/></div>
            <div><input name="shortCut" value={props.currentValue.shortcut} placeholder="Short cut" onChange = {props.updateNewPitch} /></div>
            <div><input name="subject" value={props.currentValue.subject} placeholder="Subject" onChange = {props.updateNewPitch} /></div>
            <div><textarea name="pitch" value={props.currentValue.pitch} onChange = {props.updateNewPitch}/></div>
            <button type="submit" onClick={props.savePitch} >Add Pitch</button>
        </div>
    )
}

// function SavedPitches(props)


class Form extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            inputList: [],
            addNewPitch: {
                pitchName: '',
                shortCut: '',
                subject: '',
                pitch: ''
            },
            savedPitches: []
        };
        this.onAddBtnClick = this.onAddBtnClick.bind(this)
        this.savePitch = this.savePitch.bind(this)
        this.updateNewPitch = this.updateNewPitch.bind(this)
    }

    updateNewPitch(e){
        this.setState({addNewPitch: {...this.state.addNewPitch, [e.target.name]: e.target.value}})

    }


    onAddBtnClick(event){
        const inputList = this.state.inputList;
        this.setState({
            inputList: inputList.concat(
                <Input savePitch={this.savePitch} 
                       currentValue = {this.state.addNewPitch} 
                       updateNewPitch={this.updateNewPitch} 
                />
            )
        })
    }

    render() {
        return(
            <div>
                <button onClick={this.onAddBtnClick}>Add input</button>
                <div></div>
                {
                    this.state.inputList
                }
            </div>

        )
    }
}


ReactDOM.render(<Form />,document.getElementById('root'));

1 个答案:

答案 0 :(得分:0)

原因是因为您将Input(UI元素)存储在状态变量中,并且该变量未获得更新,仅在单独的状态变量addNewPitch中更新值。

<强>建议

1-在状态变量中存储UI元素不是一个好主意,总是将值存储在状态中,并且所有ui逻辑都应该在render函数内。

2-使用状态变量并在此基础上切换Input(UI元素)。

检查工作解决方案(检查内部addNewPitch的值,渲染它将得到正确更新):

function Input(props) {
    return (
        <div>
            <div><input name="pitchName" value={props.currentValue.pitchName} placeholder="Pitch Name" onChange = {props.updateNewPitch}/></div>
            <div><input name="shortCut" value={props.currentValue.shortcut} placeholder="Short cut" onChange = {props.updateNewPitch} /></div>
            <div><input name="subject" value={props.currentValue.subject} placeholder="Subject" onChange = {props.updateNewPitch} /></div>
            <div><textarea name="pitch" value={props.currentValue.pitch} onChange = {props.updateNewPitch}/></div>
            <button type="submit" onClick={props.savePitch} >Add Pitch</button>
        </div>
    )
}


class Form extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            inputList: [],
            addNewPitch: {
                pitchName: '',
                shortCut: '',
                subject: '',
                pitch: ''
            },
            savedPitches: []
        };
        this.onAddBtnClick = this.onAddBtnClick.bind(this)
        this.savePitch = this.savePitch.bind(this)
        this.updateNewPitch = this.updateNewPitch.bind(this)
    }

    savePitch() {
    }

    updateNewPitch(e){
       this.setState({addNewPitch: {...this.state.addNewPitch, [e.target.name]: e.target.value}})
    }


    onAddBtnClick(event){
        const inputList = this.state.inputList;
        this.setState({
           show: true,
           addNewPitch: {
                pitchName: '',
                shortCut: '',
                subject: '',
                pitch: ''
            }
        })
    }

    render() {
        console.log('addNewPitch', this.state.addNewPitch);
        return(
            <div>
                <button onClick={this.onAddBtnClick}>Add input</button>
                <div></div>
                {
                    this.state.show && <Input 
                      savePitch={this.savePitch} 
                      currentValue = {this.state.addNewPitch} 
                      updateNewPitch={this.updateNewPitch} 
                  />
                }
            </div>

        )
    }
}


ReactDOM.render(<Form />,document.getElementById('root'));
<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='root'/>