Best way to get values from multiple complex child components?

Related searches

I have a parent component that has base data called script, which has multiple sequences and each sequence is composed of multiple items (inputs, dropdown, ... ).

Now I need the updated data in parent since I want to put a save button that is going to save all forms with one click.

It looks something like this:

I tried two ways of handling this:

  • That each child had an onChange property in which parent sets the state with the new data. But the problem here is, that since this is quite a complex form, it re-renders everything each time, so there was a noticeable delay when typing in inputs.
  • The "bad" of just changing the props object in a child, which is fast, but I know it is a bad practice.

What is the best way of handling forms on a scale like this? Should it be set up differently?

This is a question I've spent some time struggling with myself. There are multiple ways to maintain child state at a higher level; however, I've found that in your particular situation it is often best to use Redux.

To be clear, I generally avoid Redux at all costs (in favor of React's context), but Redux gives you the ability to subscribe to a particular piece of state in your child components. Listening to one piece of state in a child component will prevent your parent and sibling components from updating when you only need a single child to update. This ends up being far more efficient when handling multiple forms at one time.

For example, the following component will only listen to state updates that affect its own state. These updates will bypass the forms parent and sibling components:

import React from 'react';
import { connect } from 'react-redux';
import * as actions from 'redux/actions';
// Custom component
import { InputField } from 'shared';

const FormOne = ({ me, actions }) => (
  <form>
    <InputField
      inputId="f1f1"
      label="field one"
      value={me.fieldOne}
      onChange={(e) => actions.setFormOneFieldOne(e.target.value)}
    />
    <InputField
      inputId="f1f2"
      label="field two"
      value={me.fieldTwo}
      onChange={(e) => actions.setFormOneFieldTwo(e.target.value)}
    />
    <InputField
      inputId="f1f3"
      label="field three"
      value={me.fieldThree}
      onChange={(e) => actions.setFormOneFieldThree(e.target.value)}
    />
  </form>
);

export default connect(state => ({ me: state.formOne }), actions)(FormOne);

In the above example FormOne is only listening for its own state updates; whereas, similar logic utilizing context instead of Redux will cause the entire component tree that the context provider is wrapping to update (including parent and sibling components):

import React, { useContext } from 'react';
// Custom component
import { InputField } from 'shared';
// Custom context - below component must be wrapped with the provider
import { FormContext } from 'context';


const FormTwo = () => {
  const context = useContext(FormContext);

  return(
    <form>
      <InputField
        inputId="f2f1"
        label="field one"
        value={context.state.formTwo.fieldOne}
        onChange={(e) => context.setFormTwoFieldOne(e.target.value)}
      />
      <InputField
        inputId="f2f2"
        label="field two"
        value={context.state.formTwo.fieldTwo}
        onChange={(e) => context.setFormTwoFieldTwo(e.target.value)}
      />
      <InputField
        inputId="f2f3"
        label="field three"
        value={context.state.formTwo.fieldThree}
        onChange={(e) => context.setFormTwoFieldThree(e.target.value)}
      />
    </form>
  );
};

export default FormTwo;

There are some improvements that can be made to both of the above components, but they are meant to serve as an example for how to connect child components to an elevated state. It is also possible to connect to a single parent component using props, but that is the least efficient option possible, and will clutter up your architecture.

Key takeaway: Use Redux for your use case. It's the most efficient option if it is implemented correctly.

Good luck!

Avoiding deeply nested component trees, The child components have different data requirements than your current component. Then you add a new component, somewhere down your� Basic example to pass values between parent and child components in React. - ParentChild.es6

Wrap all the forms in a component that will only deal with saving all the forms data and running the "save all" function:

the wrapper component should have a state the includes all the forms data, it should probably look something like this:

class Wrapper Component extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      formsData: {},
    };
  }
}

formsData should probably be structured pretty much like that: { 0: { title:"text", type:"video", etc:"etc" }, 1: { title:"text", type:"video", etc:"etc" }} the keys (0,1, etc..) represents the form id, and can be set to any unique modifier each for has.

then make the wrapper component handle the onChange for every individual form -> every change on each individual form should uplift the new state (new updated data) and update the formsData state obj accordingly:

const onChange(formData) {
   const formattedData = {[formData.id]: {...formData}}
   this.setState({formsData: {...formsData, ...formattedData}})
}

* This is just an example of a case where in each change in each form you uplift the entire data object, you can do it in many ways

Than, the save all button should also be handled in the wrapper component, and uplift all the data you stored with it to the relevant function in a parent component / handle it itself.

Good luck!

How To Pass Data Between Components In Vue.js — Smashing , With so many different ways to share data across components, you should know which technique is best for your situation. This means that we can change our data and have any child props using that value will also Do we have to create an extremely complex hierarchy system if we want to pass data? In this tutorial, we will learn how to create a Child or nested components and host it in the App Component. Create a new application Create a new Angular application using the following command

Pass Multiple Children to a React Component with Slots, Pass Multiple Children to a React Component with Slots tag – and it can simplify data passing and make components more reusable. So not only can you pass children as a regular prop, but you can pass JSX into a prop? You could imagine that Layout could be much more complex internally, with� There is no parent child relationship between components A and B, so we cannot use first two methods to pass the data. We could use route parameters and pass some identifier to the routed

Passing data between nested components with Angular - DEV, With the change to one-way data binding in Angular, data is passed down A better way to centralize this data is through the use of services, which I'll write Create a parent and child component that is nested in the parent. In the parent. component.ts file, we're going to make an instance of the object:. The parent, child, and sibling components all receive the same treatment. We inject the DataService in the constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.

Understanding the Purpose of Nested Components, thousands of components, and managing data communication may be complex. In Angular, we can have a child component of a parent component where the child Moreover, one use of nested components is to send data from the child component to the parent How to Create Nested Components. The best way to send data from a parent component to a child is using props. Passing data from parent to child via props Declare props (array or object ) in the child

Give it a try. Cascading values and parameters are a way to pass a value from a component to all of its descendants without having to use traditional component parameters. Blazor comes with a special component called CascadingValue. This component allows whatever value is passed to it to be cascaded down its component tree to all of its descendants.

Comments
  • Thank you! I was trying to avoid Redux for simplicity, but I guess that will get hard eventually. Do you think this could be solved efficiently with PureComponent or would redux still be better?
  • React.PureComponent or React.memo are good options in some situations, but I would avoid them in yours for two reasons: 1. In general hooks is the way forward with React, so React.PureComponent restricts your architecture. 2. Your use case is fairly complex, and as it scales you'll need to elevate your state to keep a clean architecture. The two main options for that are Redux and context. In this situation Redux will be more performant.
  • To be clear here, you could still use React.memo to implement functional components even if you decided to use Redux. It probably won't add much of a performance boost for you though if everything is setup correctly.
  • I did some thinking and redux is the way to go. I should only use redux state for complex things and still use normal state when using simple components, right?
  • Yes, functional components and hooks are preferred moving forward. There are still a couple of use cases for class components, but they are very rare. You’ll know if and when you come across one.
  • Thanks, what is the difference between PureComponent and Memoized Component, they do basically the same, is the performance the same as well? Or should I use one over the other?
  • React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of classes.