React16Up
16.2
Fragment 不会被渲染的包裹组件
16.3
createContext
父子组件可以通过 props 自顶向下的传递数据
当组件深度嵌套时,从顶层组件向最内层组件传递数据就不那么方便
因为在老的
Context
中由上而下的“触发链”有可能被shouldComponentUpdate
打断。
//context.js
Provider(生产者)
Consumer(消费者)
export const {Provider,Consumer}=React.createContext();
import {Provider} from "./context"
<Provider value="{name:'Msea'}"> //value 固定写法
<App/>
<Provider>
import {Consumer} from "./context"
<Consumer>
{val=><button>{val.name}</button>}
</Consumer>
createContext,useReducer,useContext
import React, { useReducer } from "react";
const myContext = React.createContext();
const initialState = {
count:0
};
function reducer(state=initialState, action) {
switch (action.type) {
case "NUM_ADD":
return { count: state.count + 1 };
default:
return state;
}
}
const ContextProvider = props => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<myContext.Provider value={{ state, dispatch }}>
{props.children}
</myContext.Provider>
);
};
export { reducer, myContext, ContextProvider };
入口文件
import {ContextProvider} from "./store";
ReactDOM.render(
<ContextProvider>
<App />
</ContextProvider>
组件内使用
import React,{useContext} from 'react';
import { myContext } from "./store";
const One =()=>{
const { state, dispatch } = useContext(myContext);
return (
<div>
<h1>One:{state.count}</h1>
<button onClick={()=>{
dispatch({
type:"NUM_ADD"
})
}}>add</button>
</div>
)
}
16.7
React Hooks 初始化组件的一种方式,它们是一些(Hook)钩子函数
最重要的三个Hooks useState,useEffect,useContext
useState
修改状态按照顺序区分修改useState,所以给,修改useState顺序加逻辑
import React from 'react';
export default ()=> {
//初始化变量 num:0
//参数1 代表 num这个变量
//参数2 代表 操作做个变量的方法
const [count, setCount] = React.useState(0);
const countAdd=() => setCount(count + 1);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={countAdd}>
Click me
</button>
</div>
);
}
todoList
export default () => {
const [inputVal, setInputVal] = React.useState("");
const [list, setList] = React.useState([]);
const sendFn = () => {
list.push(inputVal);
setList(list);
setInputVal("")
}
return (
<div>
<h1>TodoList</h1>
<div>
<input
type="text"
value={inputVal}
onChange={e => setInputVal(e.target.value)}
/>
<button onClick={sendFn}>send</button>
<ul>
{
list.map((item, index) => (
<li key={index}>
<h1>{item}</h1>
</li>
))
}
</ul>
</div>
</div>
)
}
tabs
import React from 'react';
export default () => {
const [tabTest,setTabTest] = React.useState({
num: 0,
list: [
{
name: "Msea",
say: "我爱北京天安门"
},
{
name: "lili",
say: "我来自波士顿"
},
{
name: "luce",
say: "我是波兰人"
}
]
});
const setTabNum = (index) => {
var NewTabTest={...tabTest};
NewTabTest.num=index;
setTabTest(NewTabTest);
}
console.log("run");
return (
<div>
<h1>TodoList</h1>
<div>
<ul>
{
tabTest.list.map((item, index) => (
<li
key={index}
style={{ background:tabTest.num===index?"red":"" }}>
<span>{item.name}</span>
<button
onClick={setTabNum(index)}
>set</button>
{/*
也是可以的
<button onClick={()=>setTabs({...tabs,num:tabs.num+1})}>test</button>
*/}
</li>
))
}
</ul>
</div>
</div>
)
}
useEffect
useEffect
Hook 视作componentDidMount
、componentDidUpdate
和componentWillUnmount
的组合体。可以有多个
依赖数组依赖的值最好不要超过 3 个
React.useEffect(() => {});//每次mount与update都会执行
React.useEffect(() => { //只mount调用一次
console.log("run2");
},[]);//依赖数据 没有依赖
React.useEffect(() => {/依赖数据 没有依赖
return ()=>{
console.log("组件被销毁")
}
},[]);
//获取实时nun
React.useEffect(() => {
console.log(num*price + "被修改了");
}, [num]); //传入依赖参数
接口调用
函数化编程
const useFetch = async url => {
const respons = await fetch(url);
const res = await respons.json();
return res;
};
useEffect(() => {
useFetch("https://api.randomuser.me/").then((res)=>{});
}, []);