使用 useReducer 使分离的组件消失
Making a separated component disappear with useReducer
我目前正在学习 React Hooks 功能,所以我创建了一个小实验,如果单击按钮,就会出现一个不可见(未安装)的框;如果该框可见并且您单击页面上除该框以外的任何位置,该框将消失。我正在努力让盒子消失,我不知道是什么导致了这个错误。
初始状态和reducer:
const initialState = { visible: false };
const reducer = (state, action) => {
switch (action.type) {
case 'show':
return { visible: true };
case 'hide':
return { visible: false };
default:
return state;
}
};
盒子组件:
function Box() {
const [state, dispatch] = useReducer(reducer, initialState);
const boxElement = useRef(null);
const boxStyle = {
width: '200px',
height: '200px',
background: 'blue'
};
function hideBox(e) {
if(!boxElement.current.contains(e.target)) {
dispatch({ type: 'hide' });
}
}
useEffect(() => {
window.addEventListener('click', hideBox);
return () => {
window.removeEventListener('click', hideBox);
}
});
return <div style={boxStyle} ref={boxElement} />
}
主线:
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
function showBox() {
dispatch({ type: 'show' });
}
return (
<section>
{ state.visible && <Box /> }
<button onClick={showBox}>Show box</button>
</section>
)
}
您正在使用两个 useReducer 实例,而您只需要在 App component
级别有一个实例并通过 dispatch as a prop to Box
否则您只会更新 Box 中 useReducer 使用的状态而不是 App 组件中的状态
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
function showBox() {
dispatch({ type: 'show' });
}
return (
<section>
{ state.visible && <Box dispatch={dispatch}/> }
<button onClick={showBox}>Show box</button>
</section>
)
}
Box.js
function Box({dispatch}) {
const boxElement = useRef(null);
const boxStyle = {
width: '200px',
height: '200px',
background: 'blue'
};
function hideBox(e) {
if(!boxElement.current.contains(e.target)) {
dispatch({ type: 'hide' });
}
}
useEffect(() => {
window.addEventListener('click', hideBox);
return () => {
window.removeEventListener('click', hideBox);
}
});
return <div style={boxStyle} ref={boxElement} />
}
我目前正在学习 React Hooks 功能,所以我创建了一个小实验,如果单击按钮,就会出现一个不可见(未安装)的框;如果该框可见并且您单击页面上除该框以外的任何位置,该框将消失。我正在努力让盒子消失,我不知道是什么导致了这个错误。
初始状态和reducer:
const initialState = { visible: false };
const reducer = (state, action) => {
switch (action.type) {
case 'show':
return { visible: true };
case 'hide':
return { visible: false };
default:
return state;
}
};
盒子组件:
function Box() {
const [state, dispatch] = useReducer(reducer, initialState);
const boxElement = useRef(null);
const boxStyle = {
width: '200px',
height: '200px',
background: 'blue'
};
function hideBox(e) {
if(!boxElement.current.contains(e.target)) {
dispatch({ type: 'hide' });
}
}
useEffect(() => {
window.addEventListener('click', hideBox);
return () => {
window.removeEventListener('click', hideBox);
}
});
return <div style={boxStyle} ref={boxElement} />
}
主线:
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
function showBox() {
dispatch({ type: 'show' });
}
return (
<section>
{ state.visible && <Box /> }
<button onClick={showBox}>Show box</button>
</section>
)
}
您正在使用两个 useReducer 实例,而您只需要在 App component
级别有一个实例并通过 dispatch as a prop to Box
否则您只会更新 Box 中 useReducer 使用的状态而不是 App 组件中的状态
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
function showBox() {
dispatch({ type: 'show' });
}
return (
<section>
{ state.visible && <Box dispatch={dispatch}/> }
<button onClick={showBox}>Show box</button>
</section>
)
}
Box.js
function Box({dispatch}) {
const boxElement = useRef(null);
const boxStyle = {
width: '200px',
height: '200px',
background: 'blue'
};
function hideBox(e) {
if(!boxElement.current.contains(e.target)) {
dispatch({ type: 'hide' });
}
}
useEffect(() => {
window.addEventListener('click', hideBox);
return () => {
window.removeEventListener('click', hideBox);
}
});
return <div style={boxStyle} ref={boxElement} />
}