[reactjs] 렌더링 기능 외부에서 React Context에 액세스
Redux 대신 새로운 React Context API를 사용하여 새로운 앱을 개발 Redux
중입니다. 예를 들어 사용자 목록 을 가져와야 할 때를 사용하여 단순히 componentDidMount
내 작업을 호출 했지만 이제는 React Context를 사용하여 내 작업이 내부에 있습니다. 내 렌더링 함수 안에있는 내 소비자, 즉 내 렌더링 함수가 호출 될 때마다 내 사용자 목록을 가져 오기 위해 내 작업을 호출하고 불필요한 요청을 많이 할 것이기 때문에 좋지 않습니다.
그렇다면 componentDidMount
렌더링을 호출하는 대신 in과 같이 내 작업을 한 번만 호출 할 수있는 방법은 무엇입니까?
예를 들어 다음 코드를 살펴보십시오.
다음 Providers
과 같이 하나의 구성 요소로 모든 것을 래핑한다고 가정 해 보겠습니다 .
import React from 'react';
import UserProvider from './UserProvider';
import PostProvider from './PostProvider';
export default class Provider extends React.Component {
render(){
return(
<UserProvider>
<PostProvider>
{this.props.children}
</PostProvider>
</UserProvider>
)
}
}
그런 다음이 Provider 구성 요소를 다음과 같이 모든 앱을 래핑합니다.
import React from 'react';
import Provider from './providers/Provider';
import { Router } from './Router';
export default class App extends React.Component {
render() {
const Component = Router();
return(
<Provider>
<Component />
</Provider>
)
}
}
예를 들어 내 사용자보기에서 다음과 같이 표시됩니다.
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
render(){
return(
<UserContext.Consumer>
{({getUsers, users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
내가 원하는 것은 다음과 같습니다.
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
componentDidMount(){
this.props.getUsers();
}
render(){
return(
<UserContext.Consumer>
{({users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
그러나 물론 위의 예 getUsers
는 내 사용자 뷰 소품에 살지 않기 때문에 작동 하지 않습니다. 이것이 가능하다면 올바른 방법은 무엇입니까?
답변
편집 : 의 반응 – 후크의 도입으로 v16.8.0 , 당신은을 사용하여 기능적 구성 요소의 컨텍스트를 사용할 수있는 useContext
후크를
const Users = () => {
const contextValue = useContext(UserContext);
// rest logic here
}
편집 : 버전 16.6.0 부터. 당신은 사용 수명주기 방법에 컨텍스트를 사용할 수있다 this.context
처럼
class Users extends React.Component {
componentDidMount() {
let value = this.context;
/* perform a side-effect at mount using the value of UserContext */
}
componentDidUpdate() {
let value = this.context;
/* ... */
}
componentWillUnmount() {
let value = this.context;
/* ... */
}
render() {
let value = this.context;
/* render something based on the value of UserContext */
}
}
Users.contextType = UserContext; // This part is important to access context values
버전 16.6.0 이전에는 다음과 같은 방식으로 수행 할 수 있습니다.
라이프 사이클 방법에서 Context를 사용하려면 다음과 같이 구성 요소를 작성하십시오.
class Users extends React.Component {
componentDidMount(){
this.props.getUsers();
}
render(){
const { users } = this.props;
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}
}
export default props => ( <UserContext.Consumer>
{({users, getUsers}) => {
return <Users {...props} users={users} getUsers={getUsers} />
}}
</UserContext.Consumer>
)
일반적으로 앱에서 하나의 컨텍스트를 유지하고 위의 로그인을 HOC로 패키징하여 재사용하는 것이 좋습니다. 다음과 같이 쓸 수 있습니다.
import UserContext from 'path/to/UserContext';
const withUserContext = Component => {
return props => {
return (
<UserContext.Consumer>
{({users, getUsers}) => {
return <Component {...props} users={users} getUsers={getUsers} />;
}}
</UserContext.Consumer>
);
};
};
그런 다음 다음과 같이 사용할 수 있습니다.
export default withUserContext(User);
답변
좋아, 나는 이것을 제한하는 방법을 찾았다. with-context
라이브러리를 사용하여 모든 소비자 데이터를 구성 요소 소품에 삽입 할 수있었습니다.
그러나 동일한 구성 요소에 둘 이상의 소비자를 삽입하려면이 라이브러리를 사용하여 혼합 소비자를 만들어야하므로 코드가 우아하지 않고 비생산적입니다.
이 라이브러리에 대한 링크 : https://github.com/SunHuawei/with-context
편집 : 실제로 with-context
제공 하는 다중 컨텍스트 API를 사용할 필요가 없습니다. 실제로 간단한 API를 사용하고 각 컨텍스트에 대한 데코레이터를 만들 수 있으며 구성 요소에서 둘 이상의 소비자를 사용하려면 원하는만큼 데코레이터를 클래스 위에 선언하세요!
답변
제 부분 .bind(this)
에서는 이벤트 에 추가하는 것으로 충분했습니다 . 이것이 내 구성 요소의 모습입니다.
// Stores File
class RootStore {
//...States, etc
}
const myRootContext = React.createContext(new RootStore())
export default myRootContext;
// In Component
class MyComp extends Component {
static contextType = myRootContext;
doSomething() {
console.log()
}
render() {
return <button onClick={this.doSomething.bind(this)}></button>
}
}
답변
자식의 소품으로 액세스하려면 상위 부모 구성 요소에 컨텍스트를 전달해야합니다.