- 遗留问题: 目前只实现了触发useContext通过父级组件同步子组件,未实现同级组件之间的state同步
- reducer 根据不同的action返回不同的值
export const SINGLE = 'single';
export const DOUBLE = 'double';
export const TRIPLE = 'triple';
const numberReducer = (state, action) => {
action.number = action.number ? action.number : 1;
switch(action.type) {
case SINGLE:
return {
...state,
number: state.number + 1
}
case DOUBLE:
return {
...state,
number: state.number + 2
}
case TRIPLE:
return {
...state,
number: state.number + 3
}
default:
return {
...state
}
}
}
export default numberReducer;
- context:通过useReducer获取到对应的dispatch,将dispatch及state传递给context.provider的value,方便共享context的组件调用reducer的dispatch
import React, { useReducer } from 'react';
import numberReducer from './numberReducer';
export const NumberContext = React.createContext();
const NumberProvider = (props) => {
const [state, dispatch] = useReducer(numberReducer, {number: 1});
return <>
<NumberContext.Provider value={{state, dispatch}}>
{props.children}
</NumberContext.Provider>
</>
}
export default NumberProvider;
- index页面 通过provider将需要共享context的组件进行包裹
import React from 'react';
import ReactDOM from 'react-dom';
import Button from './Button';
import TextArea from './TextArea';
import NumberProvider from './NumberProvider';
import { SINGLE, DOUBLE, TRIPLE } from './numberReducer';
const App = () => {
return (
<>
<NumberProvider>
<TextArea />
<Button type={SINGLE} />
<Button type={DOUBLE} />
<Button type={TRIPLE} />
</NumberProvider>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
import React, { useContext } from 'react';
import { NumberContext } from './NumberProvider';
const TextArea = () => {
const numberContext = useContext(NumberContext);
console.log(numberContext)
return <p>number is { numberContext.state.number }</p>
}
export default TextArea;
- button组件 通过context调用reducer里的dispatch
import React from 'react';
import { useContext } from 'react';
import { NumberContext } from './NumberProvider';
import { TRIPLE, DOUBLE, SINGLE } from './numberReducer';
const Button = ({ type }) => {
const {dispatch} = useContext(NumberContext);
const onClickBtn = () => {
switch (type) {
case SINGLE:
dispatch({ type: SINGLE, number: 1 });
return;
case DOUBLE:
dispatch({ type: DOUBLE, number: 2 });
return;
case TRIPLE:
dispatch({ type: TRIPLE, number: 3 });
return;
default:
dispatch({ type: SINGLE, number: 1 });
return;
}
}
const getBtnComp = () => {
switch (type) {
case SINGLE:
return 'single increase';
case DOUBLE:
return 'double increase';
case TRIPLE:
return 'triple increase';
default:
return 'single increase';
}
}
return <>
<button style={stylesheet} onClick={onClickBtn}>
{getBtnComp()}
</button>
</>
}
const stylesheet = {
marginRight: '10px'
}
export default Button;
网友评论