How to make a shared state between two react components?

前端 未结 5 472
盖世英雄少女心
盖世英雄少女心 2020-11-27 07:04

I have 2 react components that need to share a state, react-router shows component A, which takes some inputs and adds it to its state, after the state has been successfully

相关标签:
5条回答
  • 2020-11-27 07:11

    You can build custom React hooks to share a state between components, I made one here. You can use it by downloading use-linked-state.js file.

    After importing useStateGateway hook, declare a gateway in parent component and pass it down to your child components

    import {useStateGateway} from "use-linked-state";
    const myGateway = useStateGateway({partA:null, partB:null});
    return (
      <>
        <ComponentA gateway={myGateway}>
        <ComponentB gateway={myGateway}>
        <ComponentPost gateWay={myGateway}>
      </>
      )
    
    

    Then you have access shared state between those three components by a custom useLinkedState hook

    import { useLinkedState } from "use-linked-state";
    
    export default function ComponentA({gateway}){
    
      const [state, setState] =  useLinkedState(gateway);
    
      <your logic>
    
    }
    

    In your logic ComponentA and ComponentB would be responsible for their part in shared object {partA:"filled by ComponentA", partB:"filled by componentB"}. Finally ComponentPost post the result if partA and partB of shared object were valid.

    In this way you can compose components and make connection between them to talk to each other.

    0 讨论(0)
  • 2020-11-27 07:12

    The dependency type between the components will define the best approach.

    For instance, redux is a great option if you plan to have a central store. However other approaches are possible:

    • Parent to Child

      1. Props
      2. Instance Methods
    • Child to Parent

      1. Callback Functions
      2. Event Bubbling
    • Sibling to Sibling

      1. Parent Component
    • Any to Any

      1. Observer Pattern
      2. Global Variables
      3. Context

    Please find more detailed information about each of the approaches here

    0 讨论(0)
  • 2020-11-27 07:12

    Either you can set up a parent child relationship then you can pass data to child components as props.

    Else, if you want to create interaction between 2 components which are not related to either(parent/child) you can either check out flux or even better redux.

    I would say you should go with redux.See Here why

    0 讨论(0)
  • 2020-11-27 07:20

    The easiest way to use a shared state between several components without rewriting your application's code to some state management system is use-between hook.

    Try this example in codesandbox

    import React, { useState } from "react";
    import { useBetween } from "use-between";
    
    // Make a custom hook with your future shared state
    const useFormState = () => {
      const [username, setUsername] = useState("");
      const [email, setEmail] = useState("");
      return {
        username, setUsername, email, setEmail
      };
    };
    
    // Make a custom hook for sharing your form state between any components
    const useSharedFormState = () => useBetween(useFormState);
    
    const ComponentA = () => {
      // Use the shared hook!
      const { username, setUsername } = useSharedFormState();
      return (
        <p>
          Username: <input value={username} onChange={(ev) => setUsername(ev.target.value)} />
        </p>
      );
    };
    
    const ComponentB = () => {
      // Use  the shared hook!
      const { email, setEmail } = useSharedFormState();
      return (
        <p>
          Email: <input value={email} onChange={(ev) => setEmail(ev.target.value)} />
        </p>
      );
    };
    
    const ComponentC = () => {
      // Use shared hook!
      const { email, username } = useSharedFormState();
      return (
        <p>
          Username: {username} <br />
          Email: {email}
        </p>
      );
    };
    
    export const App = () => (
      <>
        <ComponentA />
        <ComponentB />
        <ComponentC />
      </>
    );
    
    • For first, we create useFormState custom hook as a source for our state.
    • In the next step, we create useSharedFormState hook who uses useBetween hook inside. That hook can be used in any component who can read or update the shared state!
    • And the last step is using useSharedFormState in our components.

    useBetween is a way to call any hook. But so that the state will not be stored in the React component. For the same hook, the result of the call will be the same. So we can call one hook in different components and work together on one state. When updating the shared state, each component using it will be updated too.

    0 讨论(0)
  • 2020-11-27 07:29

    What you want is to implement some object that stores your state, that can be modified using callback functions. You can then pass these functions to your React components.

    For instance, you could create a store:

    function Store(initialState = {}) {
      this.state = initialState;
    }
    Store.prototype.mergeState = function(partialState) {
      Object.assign(this.state, partialState);
    };
    
    var myStore = new Store();
    
    ReactDOM.render(
      <FirstComponent mergeState={myStore.mergeState.bind(myStore)} />,
      firstElement
      );
    ReactDOM.render(
      <SecondComponent mergeState={myStore.mergeState.bind(myStore)} />,
      secondElement
      );
    

    Now, both the FirstComponent and SecondComponent instances can call this.props.mergeState({ . . .}) to assign state to the same store.

    I leave Store.prototype.getState as an exercise for the reader.

    Note that you can always pass the store (myStore) itself to the components; it just feels less react-y to do so.

    Here is some more documentation that might be of interest:

    React Docs: "Communicate Between Components"

    For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. Flux pattern is one of the possible ways to arrange this.

    0 讨论(0)
提交回复
热议问题