如何从子组件仅更改状态的一部分反应钩子

问题描述

我的父组件拥有这样的状态

 const [formData,setFormData]=useState({
        Basics:{
            job_title:'',job_type:null,ppo:true,emp_type:null,start_date_month:null,start_date_year:null,end_date_month:null,end_date_year:null
        },Details:{},Preferences:{},Colleges:{}
    })

我正在将整个状态的Basics对象作为道具传递给子组件。但是,我只希望子组件能够更改Basics对象,而不是整个状态,如果我直接传递setFormData

是不可能的。
<Basics state={formData.Basics} setState={setFormData}/>

有没有办法我只能将setFormData的一部分传递给孩子,使其不能修改formData的其他属性

解决方法

您可以创建一个仅更新该部分的单独函数,然后传递该函数而不是setFormData:

const setBasics = value => setFormData({
  ...formData,Basics: value
});

<Basics state={formData.Basics} setState={setBasics} />

您可以通过传递要更新的属性作为参数来进一步推广该思想:

const updateSection = (section,value) => setFormData({
  ...formData,[section]: value
});

<Basics
  state={formData.Basics}
  setState={(value) => updateSection('Basics',value)}
/>
,

好的。在这里以useReducer为例:

import React from 'react';

const intialList = {
        Basics:{
            job_title:'',job_type:null,ppo:true,emp_type:null,start_date_month:null,start_date_year:null,end_date_month:null,end_date_year:null
        },Details:{},Preferences:{},Colleges:{}
    }
const formReducer = (state,action) => {
    switch (action.type) {
    case 'UPDATE_BASICS':
      return {...state,Basics:{
        ...state.Basics,...action.data
      }};
    case 'UNDO_TODO':
      return state.map(todo => {
        if (todo.id === action.id) {
          return { ...todo,complete: false };
        } else {
          return todo;
        }
      });
    default:
      return state;
  }
}

const App = () => {
  const [form,dispatch] = React.useReducer(
    formReducer,intialList
  );

  const updateBasicsInfo = _ => {
    dispatch({
      type: "UPDATE_BASICS",//You can set your form object its just dummy data
      data: {
            job_title:'Test' + Math.random(),job_type:"test",emp_type:"test",start_date_month:"test",});
  };

  return <>
  <div>
    Current job tiltle:{form.Basics.job_title}
  </div>
  //just dummy functionality to use reducer
  <button onClick={updateBasicsInfo}>
    Update job detail
  </button>
  </>
}

export default App;

以下是演示:https://stackblitz.com/edit/react-nfvktg

注意:它仅更新基础知识字段,而没有其他任何字段!