useRedcer 및 useContext를 사용하여 사용자 정의 후크에서 작업을 디스패치하는 방법
버튼 토글을 위해 샘플을 만들었다.
이 일은 에 의해 이루어진다.useContext
(데이터 저장) 및useReducer
(데이터를 처리한다.잘 되고 있어.
CodeSandBox 링크는 어떻게 작동하는지 입니다.
version 1
버튼을 클릭할 때 바로 전송하는 것이다.
그리고 나서 나는 a를 만들었다.version 2
토글링에 대한 거야 그냥 주문제작 후크에 넣어두기만 하면 돼 근데 어떻게 된 거야?
// context
export const initialState = { status: false }
export const AppContext = createContext({
state: initialState,
dispatch: React.dispatch
})
// reducer
const reducer = (state, action) => {
switch (action.type) {
case 'TOGGLE':
return {
...state,
status: action.payload
}
default:
return state
}
}
//custom hook
const useDispatch = () => {
const {state, dispatch} = useContext(AppContext)
return {
toggle: dispatch({type: 'UPDATE', payload: !state.status})
// I tried to do toggle: () => dispatch(...) as well
}
}
// component to display and interact
const Panel = () => {
const {state, dispatch} = useContext(AppContext)
// use custom hook
const { toggle } = useDispatch()
const handleChange1 = () => dispatch({type: 'TOGGLE', payload: !state.status})
const handleChange2 = toggle // ERROR!!!
// and I tried handleChange2 = () => toggle, or, handleChange2 = () => toggle(), or handleChange2 = toggle()
return (
<div>
<p>{ state.status ? 'On' : 'Off' }</p>
<button onClick={handleChange1}>change version 1</button>
<button onClick={handleChange2}>change version 2</button>
</div>
)
}
// root
export default function App() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<AppContext.Provider value={{state, dispatch}}>
<div className="App">
<Panel />
</div>
</AppContext.Provider>
);
}
무슨 일이 일어나고 있는지 잘 모르겠어. 하지만 파견된 주(州)에 문제가 있는 것 같아.
(페이로드가 하드코드 같은 걸 처리하고 있지 않으면 효과가 있어, 지금 당장 디스패치를 해야 한다.
누가 좀 도와 줄래?고마워!!!
토글이 기능이 되어야 하는 것은 맞지만 당신은 작업 유형 UPDATE를 발송하고 있고 환원기는 그 작업으로 아무 것도 하지 않는다.
Dennis는 당신이 컨텍스트를 제공하는 초기 가치에는 의미가 없다는 것이 옳고 제공자가 그 가치를 제공할 것이기 때문에 그것을 비워두는 편이 낫다.
상태가 변경될 때 앱이 렌더링되어 메모된 값이 사용되지 않기 때문에 데니스의 useMemo 제안은 당신의 예를 최적화하지 않을 것이다.
다음은 코드의 작업 예시 및 내가 변경한 코멘트:
const { createContext, useReducer, useContext } = React;
const initialState = { status: false };
//no point in setting initial context value
const AppContext = createContext();
const reducer = (state, action) => {
switch (action.type) {
case 'TOGGLE':
return {
...state,
status: action.payload,
};
default:
return state;
}
};
const useDispatch = () => {
const { state, dispatch } = useContext(AppContext);
return {
//you were correct here, toggle
// has to be a function
toggle: () =>
dispatch({
//you dispatch UPDATE but reducer
// is not doing anything with that
type: 'TOGGLE',
payload: !state.status,
}),
};
};
const Panel = () => {
const { state, dispatch } = useContext(AppContext);
const { toggle } = useDispatch();
const handleChange1 = () =>
dispatch({ type: 'TOGGLE', payload: !state.status });
const handleChange2 = toggle; // ERROR!!!
return (
<div>
<p>{state.status ? 'On' : 'Off'}</p>
<button onClick={handleChange1}>
change version 1
</button>
<button onClick={handleChange2}>
change version 2
</button>
</div>
);
};
function App() {
const [state, dispatch] = useReducer(
reducer,
initialState
);
return (
<AppContext.Provider value={{ state, dispatch }}>
<div className="App">
<Panel />
</div>
</AppContext.Provider>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
글쎄, 그런 건 없어.React.dispatch
그것의 가치는undefined
export const AppContext = createContext({
state: initialState,
// useless
// dispatch: undefined
dispatch: React.dispatch
});
// dispatch function won't trigger anything.
const {state, dispatch} = useContext(AppContext);
버전 1은 실제로 컨텍스트를 사용하는 방법이지만, 일반적으로 새로운 개체를 할당할 때마다 추가 메모화 단계(사용 사례에 설명됨)를 추가하고자 할 것이다.{state,dispatch}
항상 렌더링을 일으킬 수 있지만state
같은 것일 수도 있다.
이러한 메모화 사용 사례 예를 참조하십시오.
내 요점이 명확하지 않으면 HMR 코멘트를 참조하십시오.
전략적 활용Memo를 사용해야 하며, 많은 구성요소가 컨텍스트에 액세스하는 경우 컨텍스트 변경 이외의 이유로 프로바이더와의 컴포넌트를 재렌더할 때 메모를 하는 것이 좋다.
'programing' 카테고리의 다른 글
.pyc 파일을 피하는 방법? (0) | 2022.03.28 |
---|---|
POST 요청을 보내는 방법? (0) | 2022.03.28 |
Vuetify : 스로틀/차단 v-autocomplete (0) | 2022.03.28 |
Radium 플러그인 사용 시 정의되지 않은 오류의 reactJs styleKeeperContext'를 가져오는 중 (0) | 2022.03.28 |
1이 뭔데?__truediv__`?><<<<<python>>>><<<<python>>><<<python>> (0) | 2022.03.28 |