create-react-app
引入ant design
componentDidMount
componentWillUnmount
图谱
这是Layout组件
const { children, showTopBar, showBottomBar } = this.props;
return (
<div>
{showTopBar && <TopBar />}
{children.content}
{children.txt}
<button onClick={children.btnClick}>button</button>
{showBottomBar && <BottomBar />}
</div>
);
这是使用Layout组件
<Layout showTopBar={false} showBottomBar={true} title="商城首页">
{/*
HomePage
*/}
{{
content: (
<div>
<h3>HomePage</h3>
</div>
),
txt: "这是个文本",
btnClick: () => {
console.log("btnClick");
}
}}
</Layout>
redux中文文档
import { createStore } from 'redux'
export default createStore((state = 0, action) => {
switch (action.type) {
case 'ADD': return state + 1
default: return state
}
})
export default class ReduxPage extends Component {
componentDidMount() {
store.subscribe(() => {
// 只要state变化了 就会执行这个函数
console.log("subscribe");
this.forceUpdate();
});
}
add = () => {
store.dispatch({ type: "ADD" });
};
render() {
return (
<div>
{/* getState是一次性的 */}
<p>{store.getState()}</p>
<button onClick={this.add}>add</button>
</div>
);
}
}
import store from './store/ReduxStore'
const render = () => {
ReactDom.render(
<App />,
document.querySelector('#root')
)
}
render()
store.subscribe(render)
react-redux中文文档
1. react-router
2. react-router中⽂⽂档
react-router包含3个库,react-router、react-router-dom和react-router-native。
react-router提供最基本的路由功能,实际使⽤的时候我们不会直接安装react-router,
⽽是根据应⽤运⾏的环境选择安装react-router-dom(在浏览器中使⽤)
或react-router-native(在rn中使⽤)。
react-router-dom和react-router-native都依赖react-router,
所以在安装时,react-router也会⾃动安装,创建web应⽤,使⽤:
npm install --save react-router-dom
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
<Router>
{/* 添加Switch表示仅匹配⼀个 解决下面的EmptyPage*/}
<Switch>
<Link to="/">⾸⻚</Link>
<Link to="/user">⽤户中⼼</Link>
{/* 根路由要添加exact,实现精确匹配 解决/ 和 /user同时显示 */}
<Route
exact
path="/"
component={HomePage}
//children={() => children} 优先级高
//render={() => render}
// children 优先级高 跟其他的Route不是互斥的
// component 优先级中 跟其他的Route互斥的
// render 优先级低 跟其他的Route互斥的
/>
<Route path="/user" component={UserPage} />
<Route component={EmptyPage} />
</Switch>
</Router>
</div>
);
}
}
purecomponent
React.PureComponent 与 React.Component 很相似。两者的区别在于 React.Component 并未实
现 shouldComponentUpdate() ,⽽ React.PureComponent 中以浅层对⽐ prop 和 state 的⽅式来
实现了该函数。
如果赋予 React 组件相同的 props 和 state, render() 函数会渲染相同的内容,那么在某些情况下使
⽤ React.PureComponent 可提⾼性能。
React.PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层⽐较。如果对象中
包含复杂的数据结构,则有可能因为⽆法检查深层的差别,产⽣错误的⽐对结果。仅在你的
props 和 state 较为简单时,才使⽤ React.PureComponent ,或者在深层数据结构发⽣变化时
调⽤ forceUpdate() 来确保组件被正确地更新。你也可以考虑使⽤ immutable 对象加速嵌套
数据的⽐较。
此外, React.PureComponent 中的 shouldComponentUpdate() 将跳过所有⼦组件树的 prop
更新。因此,请确保所有⼦组件也都是“纯”的组件。
import React, { Component, PureComponent } from "react";
export default class PureComponentPage extends PureComponent {
constructor(props) {
super(props);
this.state = {
counter: 0,
// obj: {
// num: 2,
// },
};
}
setCounter = () => {
this.setState({
counter: 100,
// obj: {
// num: 200,
// },
});
};
render() {
const { counter, obj } = this.state;
console.log("render");
return (
<div>
<h1>PuerComponentPage</h1>
<div onClick={this.setCounter}>counter: {counter}</div>
</div>
);
}
}
Hook
自定义hook
hook规则
<p>{useClock().toLocaleTimeString()}</p>
//⾃定义hook,命名必须以use开头
function useClock() {
const [date, setDate] = useState(new Date());
useEffect(() => {
console.log("date effect");
//只需要在didMount时候执⾏就可以了
const timer = setInterval(() => {
setDate(new Date());
}, 1000);
//清除定时器,类似willUnmount
return () => clearInterval(timer);
}, []);
return date;
}
Hook 就是 JavaScript 函数,但是使⽤它们会有两个额外的规则:
只能在函数最外层调⽤ Hook。不要在循环、条件判断或者⼦函数中调⽤。
只能在 React 的函数组件中调⽤ Hook。不要在其他 JavaScript 函数中调⽤。(还有⼀个地⽅可
以调⽤ Hook —— 就是⾃定义的 Hook 中。)
hook api 索引
useMemo
把“创建”函数和依赖项数组作为参数传⼊ useMemo ,它仅会在某个依赖项改变时才重新计算
memoized 值。这种优化有助于避免在每次渲染时都进⾏⾼开销的计算。
import React, { useState, useMemo } from "react";
export default function UseMemoPage(props) {
const [count, setCount] = useState(0);
const expensive = useMemo(() => {
console.log("compute");
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]);//只有count变化,这⾥才重新执⾏
const [value, setValue] = useState("");
return (
<div>
<h3>UseMemoPage</h3>
<p>expensive:{expensive}</p>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>add</button>
<input value={value} onChange={event => setValue(event.target.value)} />
</div>
);
}
useCallback
把内联回调函数及依赖项数组作为参数传⼊ useCallback ,它将返回该回调函数的 memoized 版本,
该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使⽤引⽤相等性去避
免⾮必要渲染(例如 shouldComponentUpdate )的⼦组件时,它将⾮常有⽤。
import React, { useState, useCallback, PureComponent } from "react";
export default function UseCallbackPage(props) {
const [count, setCount] = useState(0);
const addClick = useCallback(() => {
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]);
const [value, setValue] = useState("");
return (
<div>
<h3>UseCallbackPage</h3>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>add</button>
<input value={value} onChange={event => setValue(event.target.value)} />
<Child addClick={addClick} />
</div>
);
}
class Child extends PureComponent {
render() {
console.log("child render");
const { addClick } = this.props;
return (
<div>
<h3>Child</h3>
<button onClick={() => console.log(addClick())}>add</button>
</div>
);
}
}
useCallback(fn, deps) 相当于 useMemo(() => fn, deps) 。