javascript - 在react中动态创建自定义表单组件

标签 javascript reactjs

查看此gist以获得完整的图片。

基本上我会有这样的表格:

form

当您单击加号时,会出现另一行,其中包含日期和时间字段的下拉菜单。

我可以创建代码来将输入添加到表单中,但是我在各个组件(selectTimeInput 是一行)实际更新其值时遇到了问题。

MultipleDayTimeInput 中的 onChange 正在接收正确的数据,只是显示未更新。我对 react 非常陌生,所以我不知道是什么导致显示不更新......

我认为这是因为 SelectTimeInput 渲染函数没有被调用,因为传入的 props 没有被更新,但我不确定实现这一目标的正确方法。

想一想,是不是需要在MultipleDayTimeInputonChange中调用setState并且把改变的input去掉从 this.state.inputs 并读取以强制渲染触发...这对我来说似乎有点笨重...

最佳答案

当您更新状态中输入的显示值时,您需要使用 this.setState 更改状态数据并使用新数据重新渲染。使用 input.key = value 不是正确的方法。

Using State Correctly
There are three things you should know about setState().

Do Not Modify State Directly
For example, this will not re-render a component:

// Wrong
this.state.comment = 'Hello';
Instead, use setState():

// Correct
this.setState({comment: 'Hello'});
The only place where you can assign this.state is the constructor.

直接从 Facebook 阅读更多内容 here

不过,我实际上建议对您的代码进行一些重组。并不真正鼓励将组件作为状态值的一部分。我建议将不同的输入作为 this.state.inputs 中的数据对象,并循环遍历数据并在渲染方法中以这种方式构建每个显示。像这样:

假设你的 this.state.inputs 中有一个输入(并且假设你的输入是一个用于按键访问的对象):

inputs = {
    1: {
        selectedTime: 0:00,
        selectedValue: 2
    }
}

在渲染中,执行如下操作:

render() {
    let inputs = Object.keys(this.state.inputs).map((key) => {
        let input = this.state.inputs[key]
        return (<SelectTimeInput
            key={key}
            name={'option_' + key}
            placeholder={this.props.placeholder}
            options={this.props.options}
            onChange={this.onChange.bind(this, key)}
            timeValue={input.selectedTime}
            selectValue={input.selectedValue} 
         />)      
    )}
    return (
        <div>
            <button className="button" onClick={this.onAddClick}><i className="fa fa-plus" /></button>

            { inputs }
        </div>
    );
}

注意我们如何绑定(bind) onChange 上的键,以便我们知道要更新哪个输入。现在,在您的 onChange 函数中,您只需使用 setState 设置正确的输入值:

onChange(event, key) {
    this.setState({
        inputs: Immutable.fromJS(this.state.inputs).setIn([`${key}`, 'selectedTime'], event.target.value).toJS()

        // or
        inputs: Object.assign(this.state.inputs, Object.assign(this.state.inputs[key], { timeValue: event.target.value }))

    })
}

这尚未经过测试,但基本上这个 Immutable 语句将复制 this.state.inputs 并将与键匹配的对象内部的 selectedTime 值设置为 event.target.value。状态现已更新,触发重新渲染,当您在渲染中再次循环输入时,您将使用新的时间值作为组件的 timeValue

同样,对于 Object.assign 编辑,它没有经过测试,但可以在[此处]了解更多信息。 2基本上,此语句将新的 timeValue 值与 this.state.inputs[key] 对象合并,然后将该新对象与整个 this.state.inputs 对象合并。

这有意义吗?

关于javascript - 在react中动态创建自定义表单组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40774977/

相关文章:

javascript - 使用 Jest 时如何访问外部 javascript 方法/对象?

javascript - 在函数中,jQuery 选择器返回 PreviousObject 而不是所选对象

javascript - JS动画 visibility :隐藏的口吃

ruby-on-rails - react /巴别塔 : Components not rendering only on CircleCI

javascript - React 钩子(Hook)形式 - 对话框内的字段数组( Material UI)

javascript - 在 React 中使用 GET 请求中的数据并在子组件中使用

javascript - JS vue中如何将返回值放入另一个返回值中

javascript - JQuery 不删除添加的元素

javascript - 使用 VSCode 的更漂亮的 react/jsx-max-props-per-line 格式

javascript - 当我折叠、添加或删除面板时,React-hook-form 字段值会丢失