programing

컨슈머에서 프로바이더의 컨텍스트 값을 업데이트하려면 어떻게 해야 합니까?

topblog 2023. 3. 19. 17:48
반응형

컨슈머에서 프로바이더의 컨텍스트 값을 업데이트하려면 어떻게 해야 합니까?

마이콘텍스트.js

import React from "react";

const MyContext = React.createContext('test');
export default MyContext;

.js 컴포넌트에 액세스할 수

Parent.js

import MyContext from "./MyContext.js";
import Child from "./Child.js";

class Parent extends Component {

    constructor(props) {
      super(props);
      this.state = {
        Message: "Welcome React",
        ReturnMessage:""
      };
    }
    
    render() {
        return (
           <MyContext.Provider value={{state: this.state}}>      
              <Child /> 
           </MyContext.Provider>
       )
    }
}

그래서 프로바이더 컨텍스트와 프로바이더 탭에 콜링 자 컴포넌트를 가진 부모 컴포넌트를 작성했습니다.

Child.js

import MyContext from "./MyContext.js";

class Child extends Component {

    constructor(props) {
      super(props);
      this.state = {        
        ReturnMessage:""
      };
    }
    
    ClearData(context){
        this.setState({
           ReturnMessage:e.target.value
        });
        context.state.ReturnMessage = ReturnMessage
    }

    render() {
        return (
           <MyContext.Consumer>                 
              {(context) => <p>{context.state.Message}</p>}
              <input onChange={this.ClearData(context)} />
           </MyContext.Consumer>
       )
    }
}

에게는 ,, 이게 the 합니다.Consumer자 렌더링 부분에 데이터를 표시할 수 있습니다.

소비자로부터 상태를 업데이트해야 할 때 문제가 발생합니다.

프로바이더 상태를 갱신하거나 프로바이더 상태를 조작하려면 어떻게 해야 합니까?

이를 위해 useContext 후크를 사용할 수 있습니다.프로바이더의 하위 요소에서 사용하기 쉽습니다.예를 들면...

auth Context.js

import { createContext } from "react";

const authContext = createContext({
  authenticated: false,
  setAuthenticated: (auth) => {}
});

export default authContext;

Login.js(컨텍스트를 소비하는 컴포넌트)

import React, { useContext } from "react";
import authContext from "./authContext";

export default () => {
  const { setAuthenticated } = useContext(authContext);
  const handleLogin = () => setAuthenticated(true);
  const handleLogout = () => setAuthenticated(false);

  return (
    <React.Fragment>
      <button onClick={handleLogin}>login</button>
      <button onClick={handleLogout}>logout</button>
    </React.Fragment>
  );
};

마지막으로 index.js

import ReactDOM from "react-dom";
import React, { useState } from "react";

import authContext from "./authContext";
import Login from "./Login";

const App = () => {
  const [authenticated, setAuthenticated] = useState(false);

  return (
    <authContext.Provider value={{ authenticated, setAuthenticated }}>
      <div> user is {`${authenticated ? "" : "not"} authenticated`} </div>
      <Login />
    </authContext.Provider>
  );
};

ReactDOM.render(<App />, document.getElementById("container"));

보시다시피 useContext 후크를 사용하면 컨텍스트에 저장된 데이터를 쉽게 소비할 수 있습니다.물론 모든 React 훅과 마찬가지로 기능적인 컴포넌트에서만 동작합니다.

코드가 작동하는 것을 보고 싶다면.https://codesandbox.io/s/react-playground-forked-wbqsh?file=/index.displays

네스트된 컴포넌트에서 컨텍스트 업데이트

컴포넌트 트리 깊은 곳에 네스트되어 있는 컴포넌트에서 컨텍스트를 업데이트해야 하는 경우가 많습니다.이 경우 콘텍스트를 통해 함수를 전달하여 소비자가 콘텍스트를 업데이트할 수 있도록 할 수 있도록 할 수 있습니다.

teme-module.templedge

// Make sure the shape of the default value passed to
// createContext matches the shape that the consumers expect!
export const ThemeContext = React.createContext({
  theme: themes.dark,
  toggleTheme: () => {},
});

teme-scller-button.displays.

import {ThemeContext} from './theme-context';

function ThemeTogglerButton() {
  // The Theme Toggler Button receives not only the theme
  // but also a toggleTheme function from the context
  return (
    <ThemeContext.Consumer>
      {({theme, toggleTheme}) => (
        <button
          onClick={toggleTheme}
          style={{backgroundColor: theme.background}}>
          Toggle Theme
        </button>
      )}
    </ThemeContext.Consumer>
  );
}

export default ThemeTogglerButton;

app.module

import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    // State also contains the updater function so it will
    // be passed down into the context provider
    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
  }

  render() {
    // The entire state is passed to the provider
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}

function Content() {
  return (
    <div>
      <ThemeTogglerButton />
    </div>
  );
}

ReactDOM.render(<App />, document.root);

위의 예는 React Context API documents v16.8.6에서 직접 나온 것으로, 사용자로부터 콘텍스트 값을 갱신하는 권장 방법입니다.https://reactjs.org/docs/context.html#updating-context-from-a-nested-component

먼저 컨슈머에서 콘텍스트를 업데이트하려면 렌더링 기능 이외의 콘텍스트에 액세스해야 합니다.이 방법에 대한 자세한 내용은 다음을 참조하십시오.

렌더 기능 외부에서 React 컨텍스트 액세스

다음으로 콘텍스트 값을 갱신하는 핸들러를 프로바이더에서 제공해야 합니다.이 핸들러는 콘텍스트 값을 직접 변환하지 않습니다.당신의 코드는 다음과 같습니다.

Parent.js

import MyContext from "./MyContext.js";
import Child from "./Child.js";

class Parent extends Component {

    constructor(props) {
      super(props);
      this.state = {
        Message: "Welcome React",
        ReturnMessage:""
      };
    }

    updateValue = (key, val) => {
       this.setState({[key]: val});
    }
    render() {
        return (
           <MyContext.Provider value={{state: this.state, updateValue: this.updateValue}}>      
              <Child /> 
           </MyContext.Provider>
       )
    }
}

어린아이

import MyContext from "./MyContext.js";

class Child extends Component {

    constructor(props) {
      super(props);
      this.state = {        
        ReturnMessage:""
      };
    }

    ClearData(e){
        const val = e.target.value;
        this.setState({
           ReturnMessage:val
        });
        this.props.context.updateValue('ReturnMessage', val);
    }

    render() {
        return (
           <React.Fragment>
             <p>{this.props.context.state.Message}</p>}
             <input onChange={this.ClearData} />
           </React.Fragment>
       )
    }
}

const withContext = (Component) => {
   return (props) => {
       <MyContext.Consumer>    
            {(context) => {
               return <Component {...props} context={context} />
            }}
       </MyContext.Consumer>
   }
}

export default withContext(Child);

상태를 업데이트하려면 공급자 구성 요소에 함수를 작성해야 합니다.정확히 말하면 Consumer는 Provider 컴포넌트에 쓴 값과 함수만 사용할 수 있습니다.

부모 컴포넌트 내

updateReturnMessage = (ReturnMessage) => {
  this.setState((prevState) => ({ ...prevState, ReturnMessage }))
}

<MyContext.Provider value={{ state: this.state, updateReturnMessage: this.updateReturnMessage }}>
// your code goes here
</MyContext.Provider>

하위 구성 요소:

ClearData(e){
  const val = e.target.value;
  this.context.updateReturnMessage(val);
}

이 함수는 다음과 같습니다.action creators에서 이용 가능한.Redux그리고.flux

@nowshad, redux와 함께 사용하시겠습니까? 그러면 프로바이더를 사용하는 것이 좋습니다.

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
​
const store = createStore(todoApp)
​
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

를 소수의 컴포넌트에 대해서만 사용하고 있는 경우, 스테이트먼트에 따라 모든 네스트된 컴포넌트의 값을 지정할 수 있습니다.

For nested components can i have one provider and multiple consumers For an Example : 1 is an parent , 1.1 is a child to 1 and 1.1.1 is child to 1.1, Can i have provider to 1 and consumers to 1.1 and 1.1.1 

그런 다음 핸들러를 프로펠러로 전달하고 상태를 변경하고 싶은 경우 핸들러를 호출하면 컴포넌트 전체에서 값이 변경됩니다.(전체적으로 동일한 값을 필요로 하는 하위 컴포넌트가 거의 없는 경우 이 작업을 수행해야 합니다.

***Using context, we can avoid passing props through intermediate elements***

React Docs에 따름

몇 단계 아래로 소품 통과를 피하기 위해 컨텍스트를 사용하지 마십시오.여러 수준의 여러 구성 요소에서 동일한 데이터에 액세스해야 하는 경우를 고수하십시오.

콘텍스트를 사용하는 이유와 사용하지 않는 이유에 대해서는, 다음의 문서를 참조해 주세요.

콘텍스트를 사용하는 이유와 방법에 대해 아직 문제가 있거나 의문이 있는 경우 알려 주십시오.

언급URL : https://stackoverflow.com/questions/50502664/how-to-update-the-context-value-in-a-provider-from-the-consumer

반응형