react 的初步理解

state

不能直接修改state,需借助setState()

setState(partialState, callback)

  • partialState: object | Function
    用于产生与当前state合并的子集。
  • callback: Function
    state更新之后被调用。

state 的更新可能是异步

  1. setState在合成事件生命周期中是异步的,这里说的异步是批量更新,达到优化性能的目的
  2. setState在setTimeout中是同步
setData = () => {
	// 同步方式
	setTimeout(() => {
		this.changeValue()
	}, 0)
}

changeValue = () => {
	this.setState({data: this.state.data + 1})
}
  1. setState在 原生事件 中是同步
document.getElementById("test").addEventListener("click", this.setData)

state 的更新会被合并

setData = () => {
	this.changeValue()
	this.changeValue()
} // data 只会加1,不会加2

修改 changeValue 方法

changeValue = () => {
	this.setState(state => { // 接收的Function类型
		return {
			data: state.data + 1
		}
	})
}

redux

在这里插入图片描述

检查点:

  1. createStore 创建store
  2. reducer 初始化、修改状态函数
  3. getState 获取状态值
  4. dispatch 提交更新
  5. subscribe 变更订阅
// pages/ReduxDemo.js
import * as React from 'react'
import store from '../store/index'

class ReduxDemo extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            counter: store.getState()
        }
        console.log(store.getState())
    }
    componentDidMount() {
        // store 订阅,store的值发生变化时触发
        store.subscribe(() => {
            this.setState({counter: store.getState()})
        })
    }

    render() {
        return (
            <div>
                <p>{this.state.counter}</p>
                <button onClick={() => {store.dispatch({type: 'ADD'})}}>ADD</button>
            </div>

        )
    }
}

export default ReduxDemo
// store/index.js
import {createStore} from "redux";

// 定义state初始化和修改规则
function counterReducer(state = 0, action) {
    switch (action.type) {
        case 'ADD':
            return state + 1
        default:
            return state

    }

}

const store = createStore(counterReducer)

export default store

react-redux

专为react设计的redux

react-redux提供了了两个api

  1. Provider 为后代组件提供store
  2. connect 为组件提供数据和变更更⽅方法
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {Provider} from "react-redux";
import store from "./store";

ReactDOM.render(
  // 全局提供store 
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

// pages/ReduxDemo.js
import * as React from 'react'
import {connect} from 'react-redux'

class ReduxDemo extends React.Component{
    constructor(props) {
        super(props);
        const {counter} = this.props
        console.log(counter)
    }

    render() {
        const {counter, add} = this.props
        return (
            <div>
                <p>{ counter }</p>
                <button onClick={add}>ADD</button>
            </div>

        )
    }
}

export default connect(
    //mapStateToProps 把state映射到props --- Function
    //mapDispatchToProps 把dispatch映射到props --- Object
    state => {
        return {
            counter: state
        }
    },
    {
        add: () => {
            return {type: 'ADD'}
        }
    }
)(ReduxDemo)
// store/index.js
import {createStore} from "redux";

// 定义state初始化和修改规则
function counterReducer(state = 0, action) {
    switch (action.type) {
        case 'ADD':
            return state + 1
        default:
            return state

    }

}

const store = createStore(counterReducer)

export default store

react-router

react-router中奉⾏行行⼀一切皆组件的思想,路路由器器-Router、链接-Link、路路由-Route、独占-Switch、重定向-Redirect都以组件形式存在

只会渲染一个路径

//App.js
import logo from './logo.svg';
import './App.css';
import ReduxDemo from './pages/ReduxDemo'
import {BrowserRouter, Redirect, Route, Router, Switch} from "react-router-dom";
import RouterPage from "./pages/RouterPage";
import React from "react";

function App({history}) {
  return (
    <div className="App">
      <header className="App-header">
          <BrowserRouter>
          	// switch 当先匹配到 "/" 时,仅会渲染ReduxDemo
          	// 其实 "/routerPage" 中也有 "/",若用的是Router,则RouterPage也会渲染;switch则不会
              <Switch>
                  <Route exact path="/" component={ReduxDemo} />
                  <Route path="/routerPage" component={RouterPage} />
                  // 若都没有匹配上,默认走的路径
                  <Redirect to="/" />
              </Switch>
          </BrowserRouter>
      </header>
    </div>
  );
}

export default App;

// RouterPage.js
import {Component} from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
import * as React from "react";
import ReduxDemo from "./ReduxDemo";

export default class RouterPage extends Component {
    render() {
        return (
            <div>
                <p>RouterPage xxxxxxxxxxxxxxxxxxxxxxxx</p>
                <Link to="/redux">ReduxDemo</Link>
            </div>
        )
    }
}

Route渲染内容的三种⽅方式

Route渲染优先级:children>component>render。
这三种⽅方式互斥,你只能用其中一种。

children:func

有时候,不管location是否匹配,你都需要渲染一些内容,这时候你可以用children。
除了不管location是否匹配都会被渲染之外,其它工作方法与render完全一样。

render:func

但是当你用render的时候,你调用的只是个函数。
只在当location匹配的时候渲染。

component: component

只在当location匹配的时候渲染。

PureComponent 与 Component

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() 来确保组件被正确地更新。
此外, React.PureComponent 中的 shouldComponentUpdate() 将跳过所有⼦子组件树的 prop
更更新。因此,请确保所有⼦子组件也都是“纯”的组件。

import React, { Component, PureComponent } from "react";
export default class PureComponentPage extends PureComponent {
	constructor(props) {
		super(props);
		this.state = {
			counter: 0
		};
	}
	setCounter = () => {
		this.setState({
		counter: 100
		});
	}
	render() {
		const { counter, obj } = this.state;
		console.log("render");
		return (
			<div>
				<h1>PuerComponentPage</h1>
				// 不需shouldComponentUpdate生命周期函数,也会刷新View
				<div onClick={this.setCounter}>counter: {counter}</div>
			</div>
		)
	}
}

Hook

Hook 是什什么? Hook 是⼀一个特殊的函数,它可以让你“钩⼊入” React 的特性。例如, useState 是允许你在 React 函数组件中添加 state 的 Hook。

什么时候我会用 Hook? 如果你在编写函数组件并意识到需要向其添加一些 state,以前的做法是必须将其它转化为 class。现在你可以在现有的函数组件中使用 Hook。

import React, { useState } from "react";
export default function HookPage(props) {
	// 声明⼀一个叫 “count” 的 state 变量量,初始化为0
	// setCount: 改变count的值
	const [count, setCount] = useState(0);
	return (
		<div>
			<h3>HookPage</h3>
			<p>{count}</p>
			<button onClick={() => setCount(count + 1)}>add</button>
		</div>
	);
}

Effect Hook

Effect Hook 可以让你在函数组件中执⾏行行副作⽤用操作。
数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用。

// 与生命周期中的 componentDidMount 和 componentDidUpdate 类似
useEffect(() => {
	// 更新 title
	document.title = `You clicked ${count} times`;
});
  • 在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以及执行其他包含副作用的操作都是不被允许的,因为这可能会产⽣生莫名其妙的 bug 并破坏 UI 的⼀一致性。
  • 使用 useEffect 完成副作用操作。赋值给 useEffect 的函数会在组件渲染到屏幕之后执行。你可以把 effect 看作从 React 的纯函数式世界通往命令式世界的逃生通道。

Effect Hook 的条件执行

默认情况下,effect 会在每轮组件渲染完成后执行。这样的话,一旦 effect 的依赖发生变化,它就会被重新创建。

所以可以给 useEffect 传递第二个参数,它是 effect 所依赖的值数组。

useEffect(() => {
// 只有当 count 发生变化时,才会执行
document.title = `You clicked ${count} times`;
}, [count]);

Effect Hook 的释放

通常,组件卸载时需要清除 effect 创建的诸如订阅或计时器 ID 等资源。要实现这一点, useEffect函数需返回一个清除函数,以防止内存泄漏,清除函数会在组件卸载前执行。

useEffect(() => {
	const timer = setInterval(() => {
		setDate(new Date());
	}, 1000);
	// return 返回一个清除函数
	return () => clearInterval(timer);
}, []);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值