当前位置 博文首页 > 文章内容

    react萌新的读书小笔记(二)

    作者: 栏目:未分类 时间:2020-08-26 11:01:33

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    useReducer

    import React, {useReducer} from 'react'
    
    function reducer(state, action) {
        switch (action.type) {
            case 'changeName':
                return {...state, name: action.value}
            case 'changeAge':
                return {...state, age: action.value}
            case 'changeSex':
                state.sex+=1;
                return {...state }
            default:
                throw Error('报错啦')
        }
    }
    
    export default function App() {
        const [{name, age}, dispatch] = useReducer(reducer, {name:'',age:''});
        return <div>
            <input type="text"
                   value={name}
                   onChange={e => dispatch({type: 'changeName', value: e.target.value})}
            />
            <p>{name}</p>
            <input type="text"
                   value={age}
                   onChange={e => dispatch({type: 'changeAge', value: e.target.value})}
            />
            <p>{age}</p>
    		<button onClick={()=>dispatch({type:'changeSex'})}>+</button>
            {sex}
        </div>
    
    }
    
    onChange 监听
    onBlur  失去焦点
    

    useState

    复杂类型的操作

    export default function App() {
        let [num, setNum] = useState([]);
        const add1 = () => {
            setNum([...num, {
                value: num.length
            }])
        }
        const add2 = () => {
            setNum([...num.reverse()])
        }
        return <>
            <ul>
                {num.map((v, i) =>
                    (<li key={i}>{v.value}</li>))}
            </ul>
            <button onClick={() => add1()}>push</button>
            <br/>
            <button onClick={() => add2()}>reverse</button>
    
        </>
    }
    
    

    高阶方式

    export default function App() {
        let [num, setNum] = useState({
            first: 0,
        })
        const clickOne = str => {
            setNum({...num, [str]: num.first + 1})
        }
        return <>
            <button onClick={() => clickOne('first')}>First {num.first}</button>
        </>
    }
    

    组件通信

    无状态父=>无状态子

    父
    export const Four = (props) => {
        const list = [
            { title: 'A Christmas Carol', author: 'Charles Dickens' },
            { title: 'The Mansion', author: 'Henry Van Dyke' }];
        const clicks = (e) => {
            console.log(e.target.value);
        }
    
        return (<>
            xxx
            {list.map((v,i)=>{
                return <Fill title={v.title} author={v.author} inputChange={clicks} key={i}/>
            })}
        </>)
    }
    
    =========
    const Fill = props => {
    
        return (<>
            {/*<App/>*/}
            <h1>{props.title}</h1>
            <h1>{props.author}</h1>
            <input type="text" onChange={props.inputChange}/>
        </>)
    }
    

    useState 实现增删改

    import React, {useState} from 'react';
    import Headers from "./header/header";
    
    function App() {
        const [articles, setArticles] = useState([{
            id: 1,
            name: 'name1',
            hide: true
        }, {
            id: 2,
            name: 'name2',
            hide: true
        }, {
            id: 3,
            name: 'name3',
            hide: true
        }])
        const deleteAti = (id) => {
            setArticles(articles.filter(val => val.id !== id))
        }
        const addAti = () => {
            let id = articles.slice(-1)[0].id + 1;
            setArticles([
                ...articles,
                {
                    id: id,
                    name: 'name' + id,
                    hide: true
                }
            ])
        }
        const hideEdit = id => {
            let update=[...articles];
            let index = articles.findIndex(val => val.id===id);
            let hide=articles[index].hide;
            update[index]={...articles[index],hide: !hide}
            return setArticles(update)
        }
        return (<div>
                <Headers/>
                <ul>
                    {articles.map((v, i) => {
                        return <li key={i}>
                            {v.hide&&(<div>{v.name}</div>)}
                            <button onClick={() => deleteAti(v.id)}>删除</button>
                            <button onClick={() => addAti(v.id)}>增加</button>
                            <button onClick={()=>hideEdit(v.id)}>隐藏</button>
                        </li>
                    })}
                </ul>
            </div>
        );
    }
    
    export default App;
    
    

    生命周期

    getDerivedStateFromProps 接受新属性

    render setState 发生变化

    componentDidMount 调用DOM

    shouldComponentUpdate

    • 提高性格(为啥)

    实例被创建并插入DOM中时,经历的生命周期

    getDerivedStateFromProps

    constructor() 
    static getDerivedStateFromProps()
    render()
    componentDidMount()
    
    static getDerivedStateFromProps(props, state)
    当prop static发生变化
    
    export default class Headers extends Component {
        state = {
            error: null,
            users: []
        }
    
        constructor(props) {
            super(props);
        }
    
        static defaultProps = {
            loading: 'loading'
        }
    
        componentDidMount() {
            setTimeout(()=>{
                this.setState({
                    error: null, users: [
                        {id: 1, sex: '男1'},
                        {id: 2, sex: '男2'},
                        {id: 3, sex: '男3'},
                        {id: 4, sex: '男4'},
                    ]
                })
                
            },5000)
    
        }
    
        static getDerivedStateFromProps(props, state) {
            return {...state, loading: state.users.length === 0 ? props.loading : null}
        }
    
        render() {
            let {loading, users} = this.state;
            return <>
                <h1>headers</h1>
                {loading&&<div>loading</div>}
                <ul>
                    {users.map((v,i)=>{
                        return <li key={i}>{v.sex}</li>
                    })}
                </ul>
            </>
        }
    }
    

    shouldComponentUpdate

    返回等于true或者false,true指的是进行重新渲染,false指的是不需要重新渲染

       shouldComponentUpdate(nextProps, nextState, nextContext) {
            // 变化后的新数据,比如 5s后更新的数据
            console.log(nextProps);
            console.log(nextState);
            return true
        }
    

    getSnapshotBeforeUpdate

    DOM可能发生改变捕获某些信息

    getSnapshotBeforeUpdate componentDidUpdate 应该一起用,不然报错

    当DOM发生变化的时候会触发这个生命周期

     getSnapshotBeforeUpdate(prevProps, prevState) {
            // 这个是dom 发生变化的时候,返回前面的prop,state 的状态
         	console.log(prevProps);
            console.log(prevState);
            return null
        }
        componentDidUpdate(){
            
        }
    

    案例

    export default class Headers extends Component {
        state = {
            error: null,
            users: []
        }
    
        constructor(props) {
            super(props);
        }
        getSnapshotBeforeUpdate(prevProps, prevState) {
            console.log(prevProps);
            console.log(prevState);
            return null
        }
        componentDidUpdate(){
    
        }
    
        static defaultProps = {
            loading: 'loading'
        }
    
        componentDidMount() {
            setTimeout(()=>{
                this.setState({
                    error: null, users: [
                        {id: 1, sex: '男1'},
                        {id: 2, sex: '男2'},
                        {id: 3, sex: '男3'},
                        {id: 4, sex: '男4'},
                    ]
                })
    
            },5000)
    
        }
    
        static getDerivedStateFromProps(props, state) {
            return {...state, loading: state.users.length === 0 ? props.loading : null}
        }
    
        render() {
            let {loading, users} = this.state;
            return <>
                <h1>headers</h1>
                {loading&&<div>loading</div>}
                <ul>
                    {users.map((v,i)=>{
                        return <li key={i}>{v.sex}</li>
                    })}
                </ul>
            </>
        }
    }
    

    我们会发现当数据添加上去的时候,返回的之前的props,state

    {loading: "loading"}
    {error: null, users: Array(0), loading: "loading"}
    

    getSnapshotBeforeUpdate和componentDidUpdate一起使用

    可以理解用处,类似做拿到上一次的状态进行操作

    getSnapshotBeforeUpdate(prevProps, prevState) {
            return {foo:1}
        }
        componentDidUpdate(prevProps, prevState, snapshot){
            console.log(snapshot);
            // {foo: 1}   当数据更新的时候,或者数据发生变化的时候
        }
    // 从上级传过来的return,第三个参数componentDidUpdate
    

    拿到DOM节点

     constructor(props) {
            super(props);
            this.textInput=React.createRef();
        }
    
    <div ref={this.textInput}></div>
    

    当数据更新时,给更新的dom添加背景颜色

    getSnapshotBeforeUpdate(prevProps, prevState) {  1
            //拿到dom节点
            // console.log(this.textInput.current );
            //这个拿到之前的状态
            console.log(this.textInput.current.offsetHeight);
            return {boxColor:this.textInput.current.offsetHeight>20}
        }
        componentDidUpdate(prevProps, prevState, snapshot){ 2
            // 这个是拿到更新后的状态
            console.log(this.textInput.current.offsetHeight);
        }
    

    分析,我们会发现当数据更新了,1拿到的是没有更新前的dom,2拿到了更新后的dom,1和2可以根据状态进行更新值

    报错边界

    请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息

    class ErrorBoundary extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                hasError: false
            }
        }
        componentDidCatch(err, info) {
            this.setState({hasError: true})
        }
        render() {
            if(this.state.hasError) {
            
                return (
                    <div>Error occurred.</div>
                )
            } else {
             
                return this.props.children
            }
        }
    }
    
    <ErrorBoundary>
        <App />
    </ErrorBoundary>
    

    比如页面报错了,直接让他显示报错的页面

    try catch 类似

    区别

    • getDerivedStateFromError() 渲染备用UI
    • componentDidCatch() 打印错误信息
    类型 getDerivedStateFromError componentDidCatch
    指令其他操作 不可以 可以
    调用时间 渲染阶段调用 "提交"阶段被调用
    参数 err err,info

    componentWillUnmount

    卸载和销毁组件的生命周期

    组件dom传递

    let app1=<h1>app1</h1>
    let app2=<h1>app2</h1>
    
     <Headers {...{app1,app2}}/>
    
    ===========
    export default class Headers extends Component {
    		
    	render() {
            let {app1,app2}=this.props
            return <>
                {app1}
                {app2}
            </>
        }
    }