Могу ли я использовать один и тот же контекст для нескольких форм? - PullRequest
0 голосов
/ 10 ноября 2019

Я хочу использовать React Context, чтобы сохранить состояние моей формы. Могу ли я использовать один и тот же контекст для разных форм?

Вот мой пример кода. Я использую React Hooks API в этом примере

In FormContext.js

...
import {FormReducer} from './FormReducer';

export const FormContext = React.createContext({});

const FormContextProvider = (props) => {

  const formInit = props.value ? props.value : {};

  const [formContext, dispatch] = useReducer(FormReducer, formInit);

  return (
    <FormContext.Provider value={{formContext, dispatch}}>
      {props.children}
    </FormContext.Provider>
  );
}

export default FormContextProvider;

мой компонент формы Form.js

...
import {FormContext} from './FormContext';

const Form = ({name, fields}) => {

  const {formContext, dispatch} = useContext(FormContext);

  const inputOnChange = (e, label) => {
    let value = {};
    value[label] = e.target.value;
    dispatch({type:'ChangeField', value: value});
  }

  const renderInputs = () => {
    return fields.map(field => {
      return (
        <div className="field">
          <label>{field}</label>
          <input 
            type="text" 
            value={formContext[field] ?formContext[field]: '' } 
            onChange={(e) => inputOnChange(e, field)} 
            />
        </div>
      )}
    );
  }

  return (
    <div className="form">
      <h3>{name}</h3>
      <form>
        {formContext ? renderInputs() : <React.Fragment/>}
      </form>
    </div>
  );
}

Form.defaultProps = {
  name: '',
  fields: []
}

В Index.js Я обертываю два компонента Form внутри приложения

const formOne = { name: 'Form One', fields: ['username', 'email'] };
const formTwo = { name: 'Form Two', fields: ['name', 'email'] };

<App>
  <Form {...formOne}/>
  <Form {...formTwo}/>
</App>

В App.js , у меня есть две кнопки, чтобы решить, какая форма должнабыть отображенным

const App = (props) => {

  const [form, setForm] = useState('');

  const formBtnOnClick = (form) => {
    setForm(form);
  }

  const renderForm = () => {

    if (props.children) {
      const selectForm = props.children.find(child => child.props.name.toLowerCase().includes(form));

      if (selectForm) {
        return (
          <FormContextProvider>
            {selectForm}
          </FormContextProvider>
        )
      } else {
        return (<React.Fragment></React.Fragment>);
      }
    }

  }

  return (
    <div className="App">
      App
      <button onClick={(e) => formBtnOnClick('one')}>One</button>
      <button onClick={(e) => formBtnOnClick('two')}>Two</button>

      <Header text="Form" />
      {renderForm()}
      <Header />
    </div>
  );
}

Когда форма изменилась после нажатия кнопки, но контекст не изменился, значение предыдущей формы все еще существовало. Например: я изменяю значение адреса электронной почты в форме, и когда я нажимаю форму два, значение адреса электронной почты все еще существует.

Я что-то не так сделал или есть лучший вариант для этой проблемы.

1 Ответ

0 голосов
/ 10 ноября 2019

В этом случае вы должны очистить состояние с помощью dispatch('CLEAR_FORM'), где оно устанавливает все значения по умолчанию

case CLEAR_FORM:
      return {
        username: '',
        email: '',
        password: '',
        confirmPassword: '',
      };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...