简体   繁体   English

在 React 中管理同级组件之间的许多输入 - 最佳方法?

[英]Manage many inputs between sibling components in React - best approach?

I am new to this topic.我是这个话题的新手。

In the parent component App I have two siblings: SideMenu and Document在父组件 App 中,我有两个兄弟姐妹:SideMenu 和 Document

The idea is that the user inputs values (SideMenu) which will be renedered on the Document.这个想法是用户输入值(SideMenu),这些值将在文档上重新显示。 There will be more than 20 inputs.将有超过20个输入。 Since this is the first time I do this sort of state management, what are the best or maybe easiest approaches for this attempt of project.由于这是我第一次进行这种 state 管理,对于此项目尝试,最好或最简单的方法是什么。

function App() {
const [fullName, setFullName] = useState("")
const [address, setAddress] = useState("")
  return (
      <div className='app'>
        <SideMenu />
        <Document />
      </div>
  )
}
export default App 
const SideBar = () => {
  return (
    <div>
      <div className='input-group'>
        <label>Full Name:</label>
        <input type='text' />
      </div>
      <div className='input-group'>
        <label>Address:</label>
        <input type='text' />
      </div>
    </div>
  )
}
const Document = () => {
  return (
    <div>
      <h1>{fullName}</h1>
      <p>{address}</p>
    </div>
  )
}

You can use Formik library for handling many inputs.您可以使用Formik库来处理许多输入。 Wrap both components inside Formik and use formik's methods.将两个组件包装在 Formik 中并使用 formik 的方法。

import { Formik } from 'formik';

     <Formik
       initialValues={{ fullName: '', address: '' }}
       onSubmit={(values) => {
           alert(JSON.stringify(values, null, 2));
       }}
     >
       {({handleChange, values, handleSubmit}) => (
         <form onSubmit={handleSubmit}>
           <div className='app'>
               <SideMenu 
                  handleChange={handleChange} 
               />
               <Document values={values} />
           <button type="submit">Submit</button>
         </form>
       )}
     </Formik>

You dont need to create multiple states for each input.您不需要为每个输入创建多个状态。 handlChange will handle itself. handlChange将自行处理。 You just need add name or id attribute to input.您只需要在输入中添加nameid属性。 Also you can access values of each input using the values parameter like values.fullName .您还可以使用values.fullNamevalues参数访问每个输入的值。

const SideBar = ({handleChange}) => {
  return (
    <div>
      <div className='input-group'>
        <label>Full Name:</label>
        <input 
          type='text' 
          onChange={handleChange}
          name="fullName"
        />
      </div>
      <div className='input-group'>
        <label>Address:</label>
        <input 
          type='text' 
          onChange={handleChange} 
          name="address"
        />
      </div>
    </div>
  )
}

const Document = ({values}) => {
  return (
    <div>
      <h1>{values.fullName}</h1>
      <p>{values.address}</p>
    </div>
  )
}

There are a few approaches you can take to manage state in this situation:在这种情况下,您可以采用几种方法来管理 state:

  • You can pass the state values from the parent component to the child components as props, and then use them to render the data in the child components.您可以将父组件的 state 值作为 props 传递给子组件,然后使用它们在子组件中渲染数据。 This means that you would need to pass the fullName and address state values from the parent component to the Document component as props.这意味着您需要将 fullName 和地址 state 值作为 props 从父组件传递到 Document 组件。

  • You can use a state management library like Redux to manage your global state and allow you to access the state values from any component in your application.您可以使用 state 管理库(如 Redux)来管理您的全局 state 并允许您从应用程序中的任何组件访问 state 值。

  • You can use the React Context API to create a context that stores the state values, and then use a context consumer in the child components to access the state values.您可以使用 React 上下文 API 创建存储 state 值的上下文,然后在子组件中使用上下文使用者来访问 state 值。

Which approach you choose will depend on the complexity of your application and your personal preferences .您选择哪种方法将取决于您的应用程序的complexity和您的personal preferences In general, if you have a small application with only a few state values, it's usually easier to just pass the state values as props .一般来说,如果你有一个只有几个 state 值的小型应用程序,通常将state值作为props传递会更容易。 However, if you have a larger application with many state values that need to be shared across multiple components, it may be more appropriate to use a state management library or the Context API .但是,如果您有一个较大的应用程序,其中包含许多需要跨多个组件共享的 state 值,则使用state 管理库上下文 API可能更合适。

  1. Using Redux for this kind of situation is a huge anti-pattern.在这种情况下使用Redux是一个巨大的反模式。 Redux global store should be only used for global state, not local form state. Redux global store 应该只用于global state,而不是local form state。

  2. Context API is well suited when you need to pass data to multiple deeply nested children.上下文 API非常适合需要将数据传递给多个深度嵌套的子级时。 This way you do not need to pass props dozens of levels down the tree.这样你就不需要将道具传递到树下几十个级别。

  3. In any other case (ie the one in discussion) I suggest to use a container component that controls your form inputs state. Just pass them down one level by props and everything should be ok, simple and predictable.在任何其他情况下(即讨论中的情况),我建议使用一个容器组件来控制您的表单输入 state。只需通过道具将它们向下传递一个级别,一切都应该没问题,简单且可预测。

You can create an object for your form and store the form inputs in this object. Shared state can be stored in the most closest and common component (in your situation this is your parent component) according to your child components.您可以为您的表单创建一个 object 并将表单输入存储在这个 object 中。共享 state 可以根据您的子组件存储在最接近和最常见的组件中(在您的情况下,这是您的父组件)。 [1] [1]

When you make an update from a child component other child component that is sharing state will be syncronized and your state will be updated.当您从子组件进行更新时,共享 state 的其他子组件将被同步,并且您的 state 将被更新。 You shouldn't use redux like state management tools unless you are need to set a global state.你不应该像 state 一样使用 redux 管理工具,除非你需要设置一个全局的 state。

I have made a revision for your example, this scenario allows you to pass the state in the parent component to the child components and update the state in the parent component from the child components.我已经为你的例子做了修改,这个场景允许你将父组件中的 state 传递给子组件,并从子组件更新父组件中的 state。

I used a common event handler in the parent component, this functions captures the html event and we parse this event and update the state via this function. [2][3]我在父组件中使用了一个通用事件处理程序,此函数捕获 html 事件,我们解析此事件并通过此 function 更新 state。[2][3]

import "./styles.css";
import { useState } from "react";

import SideBar from "./SideBar";
import Document from "./Document";

export default function App() {
  const [values, setValues] = useState({
    fullName: "",
    address: "",
    postalCode: ""
  });

  function handleChange(event) {
    setValues({ ...values, [event.target.name]: event.target.value });
  }

  return (
    <div className="app">
      <SideBar values={values} setValues={handleChange} />
      <Document values={values} setValues={handleChange} />
    </div>
  );
}
export default function Document({ values }) {
  return (
    <div>
      <h1>Document</h1>
      <p>Full Name: {values.fullName}</p>
      <p>Address: {values.address}</p>
      <p>Postal Code: {values.postalCode}</p>
    </div>
  );
}
export default function Sidebar({ setValues }) {
  return (
    <div>
      <div className="input-group">
        <label>Full Name:</label>
        <input type="text" name="fullName" onChange={setValues} />
      </div>
      <div className="input-group">
        <label>Address:</label>
        <input type="text" name="address" onChange={setValues} />
      </div>
      <div className="input-group">
        <label>Address:</label>
        <input type="text" name="postalCode" onChange={setValues} />
      </div>
    </div>
  );
}

Code Sandbox Link: https://codesandbox.io/s/stackoverflow-74961591-wpmcnd代码沙盒链接: https://codesandbox.io/s/stackoverflow-74961591-wpmcnd

[1]: Passing Props to a component: https://beta.reactjs.org/learn/passing-props-to-a-component [1]:将 Props 传递给组件: https://beta.reactjs.org/learn/passing-props-to-a-component

[2]: Updating Objects in State: https://beta.reactjs.org/learn/updating-objects-in-state [2]:State 中的更新对象: https://beta.reactjs.org/learn/updating-objects-in-state

[3]: HTML Change Event: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event [3]:HTML 变更事件: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event

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

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