Событие onChange происходит только один раз, когда состояние управляется из-за избыточности - PullRequest
0 голосов
/ 01 апреля 2019

Я получаю массив с одним объектом из redux store.

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

И затем создание формы для обновления значения в форме реакции.

Но при попытке изменить значение событие onChange происходит только один раз.

Я управляю новым состоянием в компоненте реагирования, чтобы сохранить изменения, которые я делаю для события 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 голосов
/ 01 апреля 2019

Название вопроса немного вводит в заблуждение.В настоящее время ваше состояние не полностью управляется Redux, но только первоначально извлекается из состояния Redux.

В данный момент вы:

  1. Извлекаете состояние Redux (через реквизиты) и копируетев состояние вашего компонента в componentDidMount.
  2. Заполнение входных данных value из реквизита (из состояния Redux).
  3. Обновление состояния локального компонента с помощью onChange -> onChangeHandler.

(2) ваша проблема в настоящее время.Ваш реквизит в настоящее время не изменяется (поскольку вы не вызываете никаких действий Redux), поэтому значение вашего элемента input никогда не меняется.Это немного не интуитивно понятно, но это приводит к тому, что изменения обнаруживаются только один раз.

Вам необходимо заполнить ваш ввод value prop, используя ваше состояние.В вашей функции 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]
            ]
        })
        ...
    }

Таким образом, когда ваше состояние обновляется, «текущее» значение формы будет обновляться по-render, и компонент 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)
);
...