当状态由redux管理时,onChange事件仅发生一次

时间:2019-03-31 21:33:20

标签: node.js reactjs react-redux onchange react-redux-form

我正在从 redux 存储中获取具有单个对象的数组。

this.props.license :[0: {id: 24, domain: "xyz.com", app_url: "https...", purchase_code: "395"}]

然后创建一个表单以更新react表单中的值。

但是当尝试更改值时,onChange事件仅发生一次。

我正在管理react组件中的新状态,以保存我在onChange事件中所做的更改。

这是我编码的正确方法吗?

import React ,{Component} from 'react';
import {connect} from 'react-redux';
import * as actionCreators from '../../store/actions/index';
import Spinner from '../../components/Spinner/Spinner';

const DATABASE_LABELS={
    id:'ID',
    domain:'Domain',
    app_url:'APP URL',
    purchase_code:'Purchase Code',

}

class editLicense extends Component {

    constructor(props){
        super(props);
        this.state={
            editLicense:{}
        }
    }
    onChangeHandler=(event, type)=>{

        // [event.target.name]=[event.target.value]
        let newLicense={...this.state.editLicense}
        newLicense[type]=event.target.value
        console.log(newLicense)
         console.log('before',this.state.editLicense)

        this.setState({
            editLicense :{
                ...this.state.editLicense,
                [event.target.name]:event.target.value
            }
        })
        console.log(this.state.editLicense)
    }

    componentDidMount=()=>{  
        this.props.viewLicenceDetails(this.props.token, this.props.match.params.id)
        this.setState({
            editLicense:this.props.licenses[0]
        })
        console.log(this.state.editLicense)
    }
    render(){
        let formdata=<Spinner/>;
        if(!this.props.loading){
            let license=Object.keys(this.props.licenses[0])
            .map(key=>{
                return [
                    key,
                    this.props.licenses[0][key]
                ]
            })
            let form=license.map((p, index)=>{
                return(
                <div className="form-group" key={p[0]}>
                    <label htmlFor={p[0]}> {DATABASE_LABELS[p[0]]} </label>
                    <input type="text" className="form-control" 
                            id={p[0]} 
                            value={p[1]} 
                            name={p[0]}
                            onChange={(event) => this.onChangeHandler(event, p[0])} />
                </div>)
            })

            formdata=(
                <form>
                    {form}
                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
            )
        }
        return(
            <div className="container">
                {formdata}
            </div>
    )}
}

const mapStateToProps = (state)=>{
    return({
        token:state.auth.idToken,
        licenses:state.license.licenses,
        loading:state.license.loading,
        err:state.license.error
    })
 }

 const mapDispatchToProps = dispatch=>{
    return({
         updateLicenseData:(token, type, newVal)=>dispatch(actionCreators.updateLicense(token, type, newVal)),
         viewLicenceDetails:(token, id)=>dispatch(actionCreators.fetchOneLicense(token, id))

 })
 }
 export default connect(mapStateToProps, mapDispatchToProps)(editLicense);

1 个答案:

答案 0 :(得分:0)

问题标题有点误导。当前,您的状态尚未由Redux完全管理,而是仅最初从Redux状态获取。

您当前是:

  1. (通过props)获取Redux状态,并将其复制到componentDidMount中的组件状态。
  2. 从道具(从Redux状态)填充输入的value
  3. 通过onChange-> onChangeHandler更新本地组件状态。

(2)当前是您的问题。您的道具目前尚未更改(因为您没有调用任何Redux动作),因此input元素的值永远不会更改。有点不直观,但这导致更改仅被检测到一次。

您需要使用状态填充输入value道具。在您的render()函数中,尝试将this.props.licenses[0]的实例替换为this.state.editLicense

    if(!this.props.loading){
        let license=Object.keys(this.state.editLicense)
        .map(key=>{
            return [
                key,
                this.state.editLicense[key]
            ]
        })
        ...
    }

这样,当您更新状态时,表单的“当前”值将在重新呈现时更新,并且input组件将受到完全控制。

作为旁注:

this.setState({
    editLicense:this.props.licenses[0]
})
console.log(this.state.editLicense)

这不能保证正常工作。 setState通常应被视为异步的。如果您想响应渲染周期外的更新状态而执行某些操作,则应提供对setState的回调:

this.setState({
        editLicense:this.props.licenses[0]
    },
    () => console.log(this.state.editLicense)
);