react 状态管理
管理 state
const [count, setCount] = useState(0);
useState(value)设置初始值 value,count 是 state 的值所对应的变量,setCount(value)用来修改 count 为 value
渲染更新
当 count 变化时,就会调用 useEffect 进行渲染,如果不加条件,就是每次渲染都会更新
useEffect 相当于 componentDidMount,componentDidUpdate 和 componentWillUnmount 三个生命周期的组合。
const [count, setCount] = useState(0);
useEffect(() => {
// do something...
}, [count]);
componentDidMount
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const timeout = setTimeout(() => {
setCount(1);
}, 3000);
}, []);
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
componentWillUnmount() on return a function
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const timeout = setTimeout(() => {
setCount(1);
}, 3000);
return () => clearTimeout(timeout);
}, []);
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
when a count value is changed.
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const timeout = setTimeout(() => {
setCount(1);
}, 3000);
return () => clearTimeout(timeout);
}, [count]);
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
返回一个可变的 ref 对象,在整个生命周期内保持不变
const inputRef = useRef();
接受一个 reduce、initialArg、init,返回 state 和 dispatch,适合复杂的赋值情况,有点类似 redux
const [state, dispatch] = useReducer(reducer, initialArg, init);
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<div/>
);
}
在组件树中,传递相同的数据
定义:const MyContext = React.createContext(defaultValue);
使用:
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
import React from "react";
import { useObserver, useLocalStore } from "mobx-react";
import ReactDOM from "react-dom";
const App = () => {
const store = useLocalStore(() => ({
count: 0,
add() {
console.log(123);
this.count++;
},
}));
// const localStore = useLocalStore(() => store);
return useObserver(() => <button onClick={store.add}>{store.count}</button>);
};
ReactDOM.render(<App />, document.getElementById("container"));
import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
const counterReducer = (state = 0, action) => {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
case "ZERO":
return 0;
default:
return state;
}
};
const store = createStore(counterReducer);
const App = () => {
return (
<div>
<div>{store.getState()}</div>
<button onClick={(e) => store.dispatch({ type: "INCREMENT" })}>
plus
</button>
<button onClick={(e) => store.dispatch({ type: "DECREMENT" })}>
minus
</button>
<button onClick={(e) => store.dispatch({ type: "ZERO" })}>zero</button>
</div>
);
};
const renderApp = () => {
ReactDOM.render(<App />, document.getElementById("root"));
};
renderApp();
store.subscribe(renderApp);
从单组件的复制组件: react hooks -> react context -> mobx -> redux
单组件用 hooks 即可,多组件看复杂情况使用 context、mbox、redux