React Context API 学习笔记
创建Context Provider
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
基本概念
- React.createContext()
- Provider
- Consumer
import React from 'react';
const SuperCoolContext = React.createContext();
SuperCoolContext.Provider;
SuperCoolContext.Consumer;
计数Context
<CountContext.Provider value={0}>
<CountContext.Consumer>
{ value => <p>{value}</p> }
</CountContext.Consumer>
</CountContext.Provider>
计数Context 代码
const CountContext = createContext();
class CountProvider = extends Component {
state = { count: 0 };
increment = () => this.setState(({count}) => ({ count: count + 1}));
decrement = () => this.setState(({count}) => ({ count: count - 1}));
render() {
const { increment, decrement } = this;
const { count } = this.state;
const value = { count, increment, decrement };
return (
<CountContext.Provider value={value}>
{this.props.children}
</CountContext.Provider>
);
}
}
GrudgeContext.js
import React, { useReducer, createContext, useCallback } from "react";
import id from "uuid/v4";
import initialState from './initialState';
const GrudgeContext = createContext();
const GRUDGE_ADD = "GRUDGE_ADD";
const GRUDGE_FORGIVE = "GRUDGE_FORGIVE";
const reducer = (state, action) => {
if (action.type === GRUDGE_ADD) {
return [action.payload, ...state];
}
if(action.type === GRUDGE_FORGIVE) {
return state.map(grudge => {
if (grudge.id !== action.payload.id) return grudge;
return { ...grudge, forgiven: !grudge.forgiven };
});
}
return state;
};
export const GrudgeProvider = ({ children }) => {
const [grudges, dispatch] = useReducer(reducer, initialState);
const addGrudge = useCallback(
({ person, reason }) => {
dispatch({
type: GRUDGE_ADD,
payload: {
person,
reason,
forgiven: false,
id: id()
}
});
},
[dispatch]
);
consst toggleForgiveness = useCallback(
id => {
dispatch({
type: GRUDGE_FORGIVE,
payload: { id }
});
},
[dispatch]
);
const value = { grudges, addGrudge, toggleForgiveness };
return (
<GrudgeContext.Provider value={value}>
{children}
</GrudgeContext.Provider>
)
}
index.js 注册Context
import { GrudgeProvider } from "./GrudgeContext";
ReactDOM.render(
<GrudgeProvider>
<Application />
</GrudgeProvider>,
document.getElementById('root')
)