programing

React의 useState() 훅을 사용하여 컴포넌트 간에 상태를 공유할 수 있습니까?

lastmoon 2023. 2. 26. 10:26
반응형

React의 useState() 훅을 사용하여 컴포넌트 간에 상태를 공유할 수 있습니까?

리액트의 새로운 후크 기능을 실험하고 있었습니다.다음의 2개의 컴포넌트가 있는 것을 고려합니다(리액트 훅 사용).

const HookComponent = () => {
  const [username, setUsername] = useState('Abrar');
  const [count, setState] = useState();
  const handleChange = (e) => {
    setUsername(e.target.value);
  }

  return (
    <div>
      <input name="userName" value={username} onChange={handleChange}/>
      <p>{username}</p>
      <p>From HookComponent: {count}</p>
    </div>
  )
}


const HookComponent2 = () => {
  const [count, setCount] = useState(999);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

풀 공유 하지만, 저는 이 사이의 가 컴포넌트 간의 상태임을 되었습니다.HookComponent ★★★★★★★★★★★★★★★★★」HookComponent2공유할 수 없습니다.를 들어, 「」, 「」의 등입니다.countHookComponent2에서는, 은 행해지지 않습니다.HookComponent

할 수 ?useState()훅 훅? 훅?

컴포넌트 상태를 참조하는 경우 후크는 컴포넌트 간에 공유하는 데 도움이 되지 않습니다.구성 요소 상태는 구성 요소에 대해 로컬입니다.라면, '문맥에 맞는 상태'는요.useContext★★★★★★★★★★★★★★★★★」

기본적으로, "컴포넌트 간의 스테이트풀 로직 공유"라는 행을 잘못 이해한 것 같습니다.스테이트풀 로직은 스테이트와 다릅니다.스테이트풀 로직은 상태를 수정하는 작업입니다.를 들어, の の の の の in store 에 가입하고 componentDidMount() " " 등록 "componentWillUnmount()이 서브스크라이브/서브스크라이브 해제 동작은 훅으로 구현할 수 있으며 이 동작을 필요로 하는 컴포넌트는 훅만 사용할 수 있습니다.

컴포넌트간에 상태를 공유하는 경우는, 다양한 방법이 있습니다.각각의 장점이 있습니다.

1. 리프트업 상태

2개의 컴포넌트의 공통 상위 컴포넌트까지 상태를 올립니다.

function Ancestor() {
    const [count, setCount] = useState(999);
    return <>
      <DescendantA count={count} onCountChange={setCount} />
      <DescendantB count={count} onCountChange={setCount} />
    </>;
  }

이 상태 공유 접근방식은 기존의 상태 사용 방식과 근본적으로 다르지 않습니다. 후크는 컴포넌트 상태를 선언하는 다른 방법을 제공합니다.

2. 콘텍스트

하위 항목이 구성 요소 계층에 너무 깊이 있고 상태를 너무 많은 계층으로 전달하지 않으려면 Context API를 사용할 수 있습니다.

게 요.useContext하위 구성 요소 내에서 활용할 수 있는 후크입니다.

3. 외부 상태 관리 솔루션

Redux 또는 Mobx와 같은 상태 관리 라이브러리.그러면 상태가 React 이외의 스토어에 존재하며, 컴포넌트는 스토어에 접속/서브스크라이브하여 업데이트를 받을 수 있습니다.

외부 상태 관리 라이브러리 없이도 가능합니다.단순한 관찰 가능한 구현을 사용하면 됩니다.

function makeObservable(target) {
  let listeners = []; // initial listeners can be passed an an argument aswell
  let value = target;

  function get() {
    return value;
  }

  function set(newValue) {
    if (value === newValue) return;
    value = newValue;
    listeners.forEach((l) => l(value));
  }

  function subscribe(listenerFunc) {
    listeners.push(listenerFunc);
    return () => unsubscribe(listenerFunc); // will be used inside React.useEffect
  }

  function unsubscribe(listenerFunc) {
    listeners = listeners.filter((l) => l !== listenerFunc);
  }

  return {
    get,
    set,
    subscribe,
  };
}

.subscribeuseEffect:

const userStore = makeObservable({ name: "user", count: 0 });

const useUser = () => {
  const [user, setUser] = React.useState(userStore.get());

  React.useEffect(() => {
    return userStore.subscribe(setUser);
  }, []);

  const actions = React.useMemo(() => {
    return {
      setName: (name) => userStore.set({ ...user, name }),
      incrementCount: () => userStore.set({ ...user, count: user.count + 1 }),
      decrementCount: () => userStore.set({ ...user, count: user.count - 1 }),
    }
  }, [user])

  return {
    state: user,
    actions
  }
}

효과가 있을 거야필요 없다React.Context또는 들어올리기 상태

이것은, 를 사용하여 실행할 수 있습니다.useBetween갈고리를 채우다

코드 및 상자 참조

import React, { useState } from 'react';
import { useBetween } from 'use-between';

const useShareableState = () => {
  const [username, setUsername] = useState('Abrar');
  const [count, setCount] = useState(0);
  return {
    username,
    setUsername,
    count,
    setCount
  }
}


const HookComponent = () => {
  const { username, setUsername, count } = useBetween(useShareableState);

  const handleChange = (e) => {
    setUsername(e.target.value);
  }

  return (
    <div>
      <input name="userName" value={username} onChange={handleChange}/>
      <p>{username}</p>
      <p>From HookComponent: {count}</p>
    </div>
  )
}


const HookComponent2 = () => {
  const { count, setCount } = useBetween(useShareableState);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

React hooks 스테이트 풀 로직 이동처HookComponent로.useShareableState전화하겠습니다.useShareableState사용. useBetween각 컴포넌트에 포함되어 있습니다.

useBetween훅을 부르는 방법입니다.단, 상태가 React 컴포넌트에 저장되지 않도록 합니다.같은 훅에 대해서, 콜의 결과는 같습니다.따라서 서로 다른 컴포넌트에서 하나의 훅을 호출하여 하나의 상태에서 함께 작업할 수 있습니다.공유 상태를 업데이트하면 해당 상태를 사용하는 각 구성 요소도 업데이트됩니다.

면책사항:저는 이 책의 저자입니다.use-between패키지.

문서 상태:

useState Hook은 React에서 Import합니다.기능 컴포넌트의 로컬 상태를 유지할 수 있습니다.

컴포넌트 간에 상태를 공유할 수 있다는 것은 언급되어 있지 않다.useState훅을 사용하면 하나의 명령으로 상태 필드와 대응하는 설정자를 보다 빠르게 선언할 수 있습니다.

이 작업을 정확하게 수행할 수 있는 훅시를 만들었습니다.https://github.com/pie6k/hooksy

import { createStore } from 'hooksy';

interface UserData {
  username: string;
}

const defaultUser: UserData = { username: 'Foo' };

export const [useUserStore] = createStore(defaultUser); // we've created store with initial value.
// useUserStore has the same signature like react useState hook, but the state will be shared across all components using it

그리고 나중에 모든 컴포넌트에서

import React from 'react';

import { useUserStore } from './userStore';

export function UserInfo() {
  const [user, setUser] = useUserStore(); // use it the same way like useState, but have state shared across any component using it (eg. if any of them will call setUser - all other components using it will get re-rendered with new state)

  function login() {
    setUser({ username: 'Foo' })
  }

  return (
    <div>
      {!user && <strong>You're logged out<button onPress={login}>Login</button></strong>}
      {user && <strong>Logged as <strong>{user.username}</strong></strong>}
    </div>
  );
}

후크를 사용하는 것은 직접 가능하지 않습니다.리액션-쉬운 상태를 살펴보는 것을 추천합니다.https://github.com/solkimicreb/react-easy-state

큰 앱에서 사용하고 있는데 아주 잘 작동합니다.

난 지옥으로 갈 거야

// src/hooks/useMessagePipe.ts
import { useReducer } from 'react'

let message = undefined

export default function useMessagePipe() {
  const triggerRender = useReducer((bool) => !bool, true)[1]
  function update(term: string) {
    message = term.length > 0 ? term : undefined
    triggerRender()
  }

  return {message: message, sendMessage: update}
}

상세한 것에 대하여는, https://stackoverflow.com/a/72917627/1246547 를 참조해 주세요.


네, 이 방법은 특정 사용 사례를 해결하기 위해 제가 생각해낸 가장 지저분하고 간결한 방법입니다.또한 깔끔한 방법으로 리액션의 용이성, 또는 풋프린트가 적은 솔루션에서의 사용, 플럭스 또는 리덕스(redux)의 실제 사용 방법을 학습하는 것이 좋습니다.

Hook Component1과 Hook Component2의 상위 컴포넌트까지 상태를 올려야 합니다.이렇게 해서 이전 상태를 공유할 수 있고 최신 훅 API는 상태를 변경하지 않습니다.

언급URL : https://stackoverflow.com/questions/53451584/is-it-possible-to-share-states-between-components-using-the-usestate-hook-in-r

반응형