繁体   English   中英

通过复选框项目的本地 state 更新 redux state

[英]Updating redux state by a local state of checkbox items

stackoverflow 中有类似的问题,但我没有找到我想要的东西。 我有一个供体DonationForm,它是一个连接到 redux state 的 class 组件。 该组件的目的是收集有关想要捐赠电子产品的人的信息。 此时,我想将这些项目保存在一个数组中(将来可能使用 object)。 我的 redux state 保存捐赠者信息,减速器如下所示:

import {CHANGE_INPUT_FIELD} from '../utils/constants';

const initialStateInputs = {
    // update the state
    donorFields: {
        name: '',
        phone: '',
        area: '',
        yeshuv: '',
        address: ''
        // dateOfOffer: ''
    },
    donationFields: {
        // donorID: '',
        // vulonteerID: '',
        type: [],
        quantity: 1,
        status: 'NOT_HANDLED',
        comments: ''
        // lastDateHandled: ''
    }
    // }, items: [ //need to add quantity
    //         {id: 1, name: "LAPTOP", isChecked: false, label: 'מחשב'},
    //         {id: 2, name: "HEADPHONES", isChecked: false, label: 'אוזניות'},
    //         {id: 3, name: "OTHER", isChecked: false, label: 'אחר'},
    //     ]   
}



export const donorDonationInputsReducer = ( state = initialStateInputs, action={} ) => {
    switch(action.type) { 
        case CHANGE_INPUT_FIELD: 
            return Object.assign( {}, state, 
                {
                    donorFields :  {...state.donorFields,...action.payload},
                    donationFields:  {...state.donationFields,...action.payload},
                    // items :  {...state.items,...action.payload},
                    // isChecked:  action.payload
                }) 
        default:
            return state;
    }
}

如您所见,这些项目现在已被评论,我正在本地 state 中管理项目的 state,并且该组合的外观如下:

import React, {Component} from 'react';
import { connect } from 'react-redux';
import { setInputField } from '../actions/formAction';
import CheckBox from '../components/CheckBox/CheckBox';
import FormInput from '../components/FormInput/FormInput';
import {selectAreasOptions_2} from '../utils/constants';
import "./form.css";

const mapStateToProps = (state) => {
    return {
        donorFields: state.donorDonationInputsReducer.donorFields,
        donationFields: state.donorDonationInputsReducer.donationFields
    }
}

const mapDispatchToProps = dispatch => {
    return {
        onInputChange: event =>  {
            const {name, value} = event.target;
            dispatch(setInputField( { [name]:value} ) )
        }
    } 
}


class donorDonationForm extends Component {
    constructor() {
        super();
        this.state = {
            items: [ 
                {id: 1, name: "LAPTOP", isChecked: false, label: 'מחשב'},
                {id: 2, name: "HEADPHONES", isChecked: false, label: 'אוזניות'},
                {id: 3, name: "OTHER", isChecked: false, label: 'אחר'},
            ]
            ,
            type: []
          }
    }

    handleCheckChieldElement = (event) => {
        let {items, type} = this.state;
        let arr = [];
        items.forEach(item => {
           if (item.name === event.target.value) {
               item.isChecked = event.target.checked;
            //    console.log(`item.name  :${item.name }`);
            //    console.log(`event.target.value :${event.target.value}`);
            //    console.log(`event.target.checked :${event.target.checked}`);
           }      
        })
        items.map(item => item.isChecked ? arr.push(item.name) : null)
        this.setState({items: [...items], type: [...arr]});
        
    }

    onButtonSubmit = (event) => {
        console.log(this.props.donorFields);
        event.preventDefault();
        fetch('http://localhost:8000/api/donor', {
            method: 'post', 
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ 
                ...this.props.donorFields
            })
        })
        .then(response => response.json())
        .then(resp => console.log(resp))
        .catch( err => console.log(err) )       
    }

    // componentDidUpdate(prevProps, prevState) {
    //  const {items, type} = this.state;
    //  // const type = [];
    //  if (prevState.items !== items) {
    //      console.log('items state has changed');
    //      items.map (item => item.isChecked ? 
    //          this.setState({type: [...type,item.name]}) : null)
    //          // if (item.isChecked) { type.push(item.name) } ;
            
    //      console.log(type);
    //  }
    //   }

    render() {
        console.log(this.state.items);
        console.log(this.state.type);
        const { onInputChange } = this.props;
        return (
            <div>
                <h1 className="pt4"> פרטי תורם</h1>
                <form className=" black-80 pt2" >
                    <section className=" grid-container">
                        <FormInput 
                            id="name"
                            name="name"
                            type="text"
                            onInputChange={onInputChange}
                            label="שם "
                            required
                        />
                        <FormInput 
                            id="phone"
                            name="phone"
                            type="tel"
                            onInputChange={onInputChange}
                            label="מספר טלפון "
                            required
                        />
                        <FormInput 
                            id="address"
                            name="address"
                            type="text"
                            onInputChange={onInputChange}
                            label="כתובת "
                            required
                        />
                        <FormInput 
                            id="yeshuv"
                            name="yeshuv"
                            type="text"
                            onInputChange={onInputChange}
                            label="עיר "
                            required
                        />  
                        <FormInput 
                            id="comments"
                            name="comments"
                            onInputChange={onInputChange}
                            label="הערות "
                            required
                        />
                        <FormInput 
                            id="area"
                            name="area"
                            onInputChange={onInputChange}
                            label="איזור "
                            select={selectAreasOptions_2}
                        />
                        {/* type */}
                        <div className="measure-narrow">
                            <label htmlFor="type" className="f5 b db mb2">מעוניין לתרום
                                <span className="normal black-60"> *</span>
                            </label>
                            {
                                this.state.items.map( (item, i) => {
                                    return (
                                        <CheckBox 
                                            key={i}
                                            onChange={this.handleCheckChieldElement}
                                            checked={ item.isChecked } 
                                            value= {item.name}
                                            label = {item.label}
                                        />
                                    );
                                })
                            }
                        </div>
                    </section>
                    <input type="submit" value="שלח" 
                           className="b bg-light-blue pa2 hover pointer" 
                           onClick={this.onButtonSubmit}
                    />
                </form> 
            </div>
        );
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(donorDonationForm);

我的主要目标是类型数组 - 最终捐赠,将在提交此表单之前更新 redux state。 我尝试使用 componentDidUpdate 但没有成功。 跟踪检查项目、更新数组然后更新类型数组的最佳方法是什么,这是 redux state 中的最终捐赠? 我应该在 onButtonSubmit 方法中执行此操作吗 - 在将数据发送到服务器之前(这就是保存遍历 items 数组以搜索选中元素的方式)?

更好的方法是在onButtonSubmit里面做让我简要解释一下任务:

  1. inputChangeHandler更新this.state.items
  2. Go 和最后的this.state.itemsonButtonSubmitArray of items数组
  3. 获得 API 响应后,使用Array of items更新应用程序级别Redux state

注意:调度操作。 Reducer 将更新 Redux state。 以下代码将执行此操作:

// Action
export const setItems = (data) => (dispatch) => {
    dispatch({type: 'SET_ITEMS', payload: data})
}

// mapDispatchToProps
const mapDispatchToProps = (dispatch) =>
    bindActionCreators(
        {
            setItems,
            ...others
        },
        dispatch
    )

// onSubmitButton
    onButtonSubmit = (event) => {
        console.log(this.props.donorFields);
        event.preventDefault();
        fetch('http://localhost:8000/api/donor', {
            method: 'post', 
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ 
                ...this.props.donorFields
            })
        })
        .then(response => this.props.setItems(response.json())) // will update the state.
        .then(resp => console.log(resp))
        .catch( err => console.log(err) )       
    }

// Reducer
export const donorDonationInputsReducer = ( state = initialStateInputs, action={} ) => {
    switch(action.type) { 
        case CHANGE_INPUT_FIELD: 
            return Object.assign( {}, state, 
                {
                    donorFields :  {...state.donorFields,...action.payload},
                    donationFields:  {...state.donationFields,...action.payload},
                    // items :  {...state.items,...action.payload},
                    // isChecked:  action.payload
                })
        case SET_ITEMS:
            return {
                ...state,
                items: action.payload
            }
        default:
            return state;
    }
}

而已。

快乐编码:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM