2

複数のタブに分かれるフォームを作成しています。React Context API を使用して、フォーム入力の状態を取得し、プロバイダーで状態を設定しています。これは、フォームの入力場所にある私のコンシューマーでうまくいきます。ただし、フォームの最後のタブには、すべてのステップでフォームの入力を確認できるビューもあります。その場所のプロバイダーは、React Dev Tools のデフォルトの状態値のみを表示するため、コンシューマーを更新できません。プロバイダーの 2 番目のインスタンス化の状態が更新されず、小道具としてレビュー セクションに渡されない理由がわかりません。をプロバイダーからエクスポートcreateContext()し、レビュー セクション コンシューマーとフォーム入力セクション コンシューマーにインポートしています。
いくつかのコードを次に示します。

プロバイダー:

import React, { Component } from "react";
import moment from 'moment';
import PropTypes from 'prop-types';

const defaultDateState = moment();

const daysWeek = [
    {name: 'All'},
    {name: 'Sunday'},
    {name: 'Monday'},
    {name: 'Tuesday'},
    {name: 'Wednesday'},
    {name: 'Thursday'},
    {name: 'Friday'},
    {name: 'Saturday'}
];
const descMaxChars = 512;

export const BasicContext = React.createContext();

class BasicInfoProvider extends Component {
    state = {
        basicDesc: null,
        startDate: defaultDateState,
        endDate: defaultDateState,
        daysOfWeek: null,
        dayWeek: [],
        dayWeekOptions: daysWeek,
        descCharsLeft: descMaxChars,
    };

    //handle dates
    handleChangeStart = (date) => {
        console.log(date);
        this.setState({
          startDate: date
        });
      }

      handleChangeEnd = (date) => {
        this.setState({
          endDate: date
        });
      }


    handleChangeDesc = (e) => {
        var input = e.target.value;
        this.setState({
            basicDesc: input,
            descCharsLeft: descMaxChars - input.length
        });
    }

    handleDaysWeek = (e) => {
        console.log('days week selection', e.target.value)
        const daySelection = e.target.value;
        let daySelectionArr;
        if(this.state.dayWeek.indexOf(daySelection) > -1) {
            daySelectionArr = this.state.dayWeek.filter(s => s !== daySelection)
        } else {
            daySelectionArr = [...this.state.dayWeek, daySelection];
        }
        this.setState({ dayWeek: daySelectionArr });
    }


    render(){
       return(
            <React.Fragment>
                <BasicContext.Provider value={{
                    state: this.state,
                    actions: {
                        handleChangeDesc: this.handleChangeDesc,
                        handleChangeEnd: this.handleChangeEnd,
                        handleChangeStart: this.handleChangeStart,
                        handleDaysWeek: this.handleDaysWeek
                    },
                }}>
                    {this.props.children}
                </BasicContext.Provider> 
            </React.Fragment>

       )
    }
}

export const contextTypes = {
        basicDesc: PropTypes.string,
        startDate: PropTypes.number,
        endDate: PropTypes.number,
        daysOfWeek: PropTypes.string,
        dayWeek: PropTypes.array,
        dayWeekOptions: PropTypes.array,
        descCharsLeft: PropTypes.number,
}

export default BasicInfoProvider;

フォーム入力コンシューマー:

    import React, { Component } from "react";
import DateElement from "../DateElement";
import { Button, ButtonToolbar, FormGroup, ControlLabel, Checkbox, FormControl, HelpBlock, Modal, Glyphicon } from "react-bootstrap";
import DatePicker from 'react-datepicker';
import Select from 'react-select';
import { BasicContext, contextTypes } from './BasicInfoProvider';
import {getContext} from '../../utilities/GetContext';

import 'react-datepicker/dist/react-datepicker.css';
import 'react-select/dist/react-select.css';

class BasicInfoForm extends Component {
    render(){
        return(
            <section className="basic-info-section">
                <BasicContext.Consumer >
                    {({state, actions}) => (
                    <React.Fragment>
                        <div className="row">
                            <FormGroup
                                controlId="desc-field"
                            >
                                <h3>Description</h3>
                                <FormControl
                                    type="textarea"
                                    value={state.basicDesc}
                                    placeholder="Enter Your Description Here"
                                    onChange={actions.handleChangeDesc}
                                    maxLength="512"
                                />
                                <FormControl.Feedback />
                                <HelpBlock>Characters left: {state.descCharsLeft}</HelpBlock>
                            </FormGroup>
                        </div>

                     <hr/>

                        <div className="row">
                            <div className="date-picker-duo col-sm-6">
                                <div className="col-xs-6">
                                    <h3>Start Date</h3>
                                    <DatePicker
                                    inline
                                    selected={state.startDate}
                                    selectsStart
                                    onChange={actions.handleChangeStart} 
                                    placeholderText='Click to select a date'
                                    className="start-date-field"
                                    />
                                </div>
                                <div className="col-xs-6">
                                    <h3>End Date</h3>
                                    <DatePicker
                                    inline
                                    selected={state.endDate}
                                    selectsend
                                    onChange={actions.handleChangeEnd} 
                                    placeholderText='Click to select a date'
                                    className="end-date-field"
                                    />
                                </div>
                            </div>
                            <FormGroup bsClass="col-sm-6" controlId="formControlsSelectMultiple">
                                <h3 className="days-checkbox-title">Days of the Week</h3>
                                {state.dayWeekOptions.map((day) => {
                                    return(
                                        <div className="weekday-checkbox col-xs-3">
                                            <input 
                                                value={day.name}
                                                onChange={actions.handleDaysWeek} 
                                                type="checkbox" 
                                                id={day.name}
                                                key={day.name} />
                                            <label htmlFor={day.name}>{day.name}</label>
                                        </div>
                                    )
                                })}

                            </FormGroup>

                        </div>
                    </React.Fragment>
                    )}
                </BasicContext.Consumer>

                </section>
            );
    }
};

export default BasicInfoForm = getContext(contextTypes)(BasicInfoForm);

レビュー セクションの利用者

import React from 'react';
import { BasicContext, contextTypes } from './BasicInfoProvider';
import {getContext} from '../../utilities/GetContext';

const finalReview = (props) => {
    return(
        <div className="row">
            <h2>So you're all done with your new Promotion?</h2>

            <p>Take another look at what you're about to submit and if you like how it looks, send it on through!</p>
            <div className="well">

                <header className="review-section-header">
                    <h3>Basic Info </h3> 
                    <span className="review-edit" onClick={() => this.handleTabSelect(1)}>Edit Section</span>
                </header>
                <BasicContext.Consumer >
                    {({state}) => (
                <div className="review-group">
                    <p>
                        <span className="review-title">Description: </span> 
                        <span className="review-value">{state.basicDesc}</span>
                    </p>
                    <p>
                        <span className="review-title">Promotion Start Date: </span> 
                        <span className="review-value">{state.startDate.toString()}</span>
                    </p>
                    <p>
                        <span className="review-title">Promotion End Date: </span> 
                        <span className="review-value">{state.endDate.toString()}</span>
                    </p>
                    <p>
                        <span className="review-title">Promotion Days of the Week: </span> 
                        <span className="review-value"> 
                            {state.dayWeek.map((day) => {
                                return( `${day}, `)
                            })}
                        </span>
                    </p>
                </div>
                )}
                </BasicContext.Consumer>

            </div>
        </div>
    )
}

const FinalReview = getContext(contextTypes)(finalReview);

export default FinalReview;

getContextContextTypes を渡す単純な HOC です。 BasicInfoFormはフォーム内のタブに存在するフォームの子コンポーネントですが、プロバイダーはそこに直接行くので、タブは関係ないと思います。

私の期待は、が渡された関数を呼び出すBasicInfoProviderときにBasicInfoForm更新され、その更新が使用されているすべての場所に反映されることですが、コンポーネントBasicInfoProviderに使用されている場合はそうではありませんFinalReview

4

0 に答える 0