react总结

react总结

一、三大部分state、prop、ref
props
MyComponent.propTypes = {
    // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
   optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,
 
    // 可以被渲染的对象 numbers, strings, elements 或 array
    optionalNode: React.PropTypes.node,
 
    //  React 元素
    optionalElement: React.PropTypes.element,
 
    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),
 
    // 用 enum 来限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
 
    // 可以是多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),
 
    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
 
    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
 
    // 特定 shape 参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),
 
    // 任意类型加上 `isRequired` 来使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,
 
    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,
 
    // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  }
}
二、生命周期
旧的生命周期:
初始化阶段:

constructor–>componentWillMount(消息订阅、发送请求)–>render–>componentDidMount

数据类型

更新阶段:

(componentWillReceiveProps组件传值是接收新的值nextPorps)–>shouldComponentUpdate(控制组件更新的“阀门”一般返回true,返回false就结束nextPorps,nextState)–>componentWillUpdate–>render–>componentDidUpdate

卸载:

componentWillUnmount

(卸载DOM:ReactDOM.unmountComponentAtNode(document.getElementById(‘test’)))

新的生命周期
初始化阶段:

constructor–>getDerivedStateFromProps(含有两个参数,第一个参数是传递过来的prop,第二个是state,返回新的state,不能使用this)–>render–>compoenetDidMount

跟新阶段:

getDerivedStateFromProps->shouldComponentUpdate–>render–>getsnapsshotBeforeUpdate(得到修改之前的快照)–>componentDidUpdate(接受三个参数preProps,preState,snapshotValue)

卸载组件: 由ReactDOM.unmountComponentAtNode()触发

componentWillUnmount()

相关面试题:
1.react的生命周期都有哪些
2.React废除了哪些生命周期为什么

废弃了componentWillmount、componentWillUpdate、componentWillDerivedProps

原因是这三个函数秀在render之前,因为fiber的出现,很可能出现因为优先级任务的出现打断现有任务,导致他们被执行多次

3.React16x中props改变后在那个生命周期中处理

getDerivedStateFromProps

4.react性能优化在那个生命周期,优化的原理是什么

shouldComponentUpdate ,原理是diff算法

5.state和props触发更新的生命周期分别有什么区别

在16之前props变化调用componentwillDeceivePops,state调用componentShouldUpdate

在16之后都一起调用getDerivedStatefromProps

6.react中发起网络请求应该在那个生命周期中执行,为什么

componnetDidMount, componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重新渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。与组件上的数据无关的加载,也可以在constructor里做,但constructor是做组件state初绐化工作,并不是做加载数据这工作的,constructor里也不能setState

7.react16中新的生命周期有哪些

getDerivedStateFromProps/getSnapshotBeforeUpdate

组件通信
1.props

父传子:

父组件:todos={todos}

子组件:const {todos} = this.props

(yarn add prop-types import PropTypes from ‘prop-types’)

//对接收的props进行:类型、必要性的限制
static propTypes = {
    todos:PropTypes.array.isRequired,
    updateTodo:PropTypes.func.isRequired,
    deleteTodo:PropTypes.func.isRequired,
}

子传父:

子组件调用父组件传递的方法,通过参数传递值

子组件:

handleDelete = (id)=>{
    if(window.confirm('确定删除吗?')){
        this.props.deleteTodo(id)
    }
}

父组件:

deleteTodo = (id)=>{
    //获取原来的todos
    const {todos} = this.state
    //删除指定id的todo对象
    const newTodos = todos.filter((todoObj)=>{
        return todoObj.id !== id
    })
    //更新状态
    this.setState({todos:newTodos})
}
2.消息订阅-发布

工具库:PubSubJS 下载:yarn add pubsub-js --save

使用:

 import PubSub from 'pubsub-js' //引入

 PubSub.publish('delete', data) //发布消息

 PubSub.subscribe('delete', function(data){ }); //订阅

发布消息:

PubSub.publish('atguigu',{isFirst:false,isLoading:true})

订阅消息:第二个参数的横线代表消息名称,可以不用管

componentDidMount(){
    this.token = PubSub.subscribe('atguigu',(_,stateObj)=>{
        this.setState(stateObj)
    })
}

componentWillUnmount(){
    PubSub.unsubscribe(this.token)
}
3.集中式管理

redux

4.context 生产者-消费者模式
//创建Context对象
const MyContext = React.createContext()
const {Provider,Consumer} = MyContext

生产者(祖先组件)

<Provider value={{username,age}}>
    <B/>
</Provider>

中间组件

class B extends Component {
    render() {
        return (
            <div className="child">
                <h3>我是B组件</h3>
                <C/>
            </div>
        )
    }
}

消费者(子组件)

<Consumer>
    {value => `${value.username},年龄是${value.age}`}
</Consumer>

1.父子组件的通信方式

props

2.跨级组件的通信方式

消息订阅-发布、集中式管理、conText(用的少)

3.非嵌套组件的通信方式

消息订阅-发布、集中式管理

4.如何解决props层级过深的问题

context 或集中管理redux

5.组件通信方式有哪些
redux
原始redux

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lH6hStwy-1627349634767)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\1626054235119.png)]

1.action

在redux中建立action.js,在次文件中生成action对象,提供给组件使用:用store.dispatch来分发

生成action对象:

//同步action,就是指action的值为Object类型的一般对象
export const createIncrementAction = data => ({type:INCREMENT,data})
export const createDecrementAction = data => ({type:DECREMENT,data})

//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。
// 当检查到返回的不是对象时,会自动识别为异步anction传入dispath,就不需要用store去调用dispath了
export const createIncrementAsyncAction = (data,time) => {
	return (dispatch)=>{
		setTimeout(()=>{
			dispatch(createIncrementAction(data))
        },time)
	}
}


// 若为异步action,需要在store.js中配置中间键applyMiddleware(thunk)
export default createStore(countReducer,applyMiddleware(thunk))


store.js

用于暴露一个store对象,整个应用只有一个store

/* 
	该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/

//引入createStore,专门用于创建redux中最为核心的store对象
import {createStore,applyMiddleware} from 'redux'
//引入为Count组件服务的reducer
import countReducer from './count_reducer'
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
//暴露store
export default createStore(countReducer,applyMiddleware(thunk))

reducer.js

获取action中的action对象,接收prestate和action对象,同过action中的type匹配来执行不同的动作

/* 
	1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数
	2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
*/
import {INCREMENT,DECREMENT} from './constant'

const initState = 0 //初始化状态
export default function countReducer(preState=initState,action){
    // console.log(preState);
    //从action对象中获取:type、data
    const {type,data} = action
    //根据type决定如何加工数据
    switch (type) {
        case INCREMENT: //如果是加
            return preState + data
        case DECREMENT: //若果是减
            return preState - data
        default:
            return preState
    }
}

redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写使用subscribe

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './redux/store'

ReactDOM.render(<App/>,document.getElementById('root'))

store.subscribe(()=>{
	ReactDOM.render(<App/>,document.getElementById('root'))
})

在组件中直接导入action然后分发

//加法
increment = ()=>{
    const {value} = this.selectNumber
    store.dispatch(createIncrementAction(value*1))
}
//减法
decrement = ()=>{
    const {value} = this.selectNumber
    store.dispatch(createDecrementAction(value*1))
}

react-redux

redux中的内容和上面一样,多了一个容器组件用来连接UI和redux

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rvvIvNvH-1627349634773)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\1626056509855.png)]

容器组件中的connect

connect()() 第一次调用传递两个参数mapStateToProps–映射状态,mapDispathToProps–映射操作状态的方法返回值是一个对象;第二次调用的参数是UI组件

import {
    createIncrementAction,
    createDecrementAction,
    createIncrementAsyncAction
} from '../../redux/count_action'

//引入connect用于连接UI组件与redux
import {connect} from 'react-redux'
//使用connect()()创建并暴露一个Count的容器组件
export default connect(
    state => ({count:state}),
    //mapDispatchToProps的一般写法
    /* dispatch => ({
		jia:number => dispatch(createIncrementAction(number)),
		jian:number => dispatch(createDecrementAction(number)),
		jiaAsync:(number,time) => dispatch(createIncrementAsyncAction(number,time)),
	}) */

    //mapDispatchToProps的简写
    {
        jia:createIncrementAction,
        jian:createDecrementAction,
        jiaAsync:createIncrementAsyncAction,
    }
)(Count)

## 5.求和案例_react-redux优化

​ (1).容器组件和UI组件整合一个文件

​ (2).无需自己给容器组件传递store,给包裹一个即可。

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './redux/store'
import {Provider} from 'react-redux'

ReactDOM.render(
	<Provider store={store}>
		<App/>
	</Provider>,
	document.getElementById('root')
)

​ (3).使用了react-redux后也不用再自己检测redux中状态的改变了subscribe,容器组件可以自动完成这个工作。

​ (4).mapDispatchToProps也可以简单的写成一个对象

​ (5).一个组件要和redux“打交道”要经过哪几步?

​ (1).定义好UI组件—不暴露

​ (2).引入connect生成一个容器组件,并暴露,写法如下:

​ connect(

​ state => ({key:value}), //映射状态

​ {key:xxxxxAction} //映射操作状态的方法

​ )(UI组件)

​ (4).在UI组件中通过this.props.xxxxxxx读取和操作状态

多个reducer

在store.js中使用combineReducers将reducers合并

import {createStore,applyMiddleware,combineReducers} from 'redux'

//汇总所有的reducer变为一个总的reducer
const allReducer = combineReducers({
	he:countReducer,
	rens:personReducer
})

在container中若要用其他的redux,就要在改文件暴露完

export default connect(
	state => ({yiduiren:state.rens,he:state.he}),//映射状态
	{jiaYiRen:createAddPersonAction}//映射操作状态的方法
)(Person)

1.对redux的理解,主要解决什么问题

redux是一种状态管理器,是一种解决组件通信和数据共享的解决方案,主要包含store–储存当前state的对象

action–接受state的改变指令;reducer–action的处理器,解决问题:1、组件通信、2.通过对象驱动组件进入生命周期

2.redux原理及工作流程

组件中通过store.dispath分发action给store,store接收到action后,将节后到的action和之前的state一起传递给reducer,reducer通过匹配action中的type,执行相应的操作,最后store改变state来进行页面数据驱动

2.redux原理及工作流程
3.redux中的异步请求怎么处理
4.redux怎么实现属性传递,介绍一下原理 发布者订阅者模式
5.redux中间键是什么,接收几个参数,科里化函数两端的参数具体是什么
6.redux请求中间键如何处理并发
7.redux状态管理器和变量挂载到window有什么区别

redux中的state要改变只能通多reducer,要出发reducer就需要触发相应的action,所以redux跟晒数据的入口只有action,数据是单向的,而window上锁挂载的数据是可以任意修改的,无限的,这样的程序非常不可控

8.mobox和redux有什么区别

store是应用管理数据的地方,在Redux应用中,我们总是将所有共享的应用数据集中在一个大的store中,而Mobx则通常按模块将应用状态划分,在多个独立的store中管理。

9.redux和vuex有什么区别,他们的共同思想是什么
10.redux中间键是怎么拿到store和action的,然后怎么处理
11.redux中的connect有什么作用
hooks
1.statehook

让函数式组件也可以有state状态,并进行状态数据的读写操作

const [count,setCount] = React.useState(0)
function add(){
    //setCount(count+1) //第一种写法
    setCount(count => count+1 )
}

uesState:参数是第一次初始化的值,返回值是包含两个元素的数组,第一个为内部当前状态值,2个是更新状态值的函数

2.effect hook

让函数式组件有生命周期函数

useEffect(() => {

​ // 在此可以执行任何带副作用操作

​ return () => { // 在组件卸载前执行

​ // 在此做一些收尾工作, 比如清除定时器/取消订阅等 相当于componentWillUNmount

​ }

​ }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行相当于componentDidMount,有值的话就相当于componentUpdate

React.useEffect(()=>{
    let timer = setInterval(()=>{
        setCount(count => count+1 )
    },1000)
    return ()=>{
        clearInterval(timer)
    }
},[])

3.ref hook

储存、查找组件内的标签或任意其他数据

语法: const refContainer = useRef()

作用:保存标签对象,功能与React.createRef()一样

const myRef = React.useRef()
//提示输入的回调
function show(){
    alert(myRef.current.value)
}

<input type="text" ref={myRef}/>

1.对react hook的理解,他的原理是什么
2.为什么useState要使用数组而不是对象
3.react hook解决了哪些问题

Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数

4.react hook 的使用限制有哪些
5.useEffect与useLayoutEffect的区别
6.react hook在平时开发中需要注意哪些问题,原因是什么
7.react hooks和声明周期的关系
render props

实现自荐内部动态传入带内容的结构、标签,相当于vue中的slot

受控数据指的是组件中通过props传入的数据,受到父组件的影响

基础组件
1.react事件机制
2.react的事件和普通事件有什么不同
  • React 中的事件机制分为两个阶段:事件注册、事件分发。所有的事件都会注册到 document 上,然后使用统一的回调函数 dispatchEvent 来执行分发。 **采用事件代理的模式:在根节点document上为每种事件添加唯一的Listener,然后通过事件的target找到真实的触发元素。**这样从触发元素到顶层节点之间的所有节点如果有绑定这个事件,React都会触发对应的事件处理函数。这就是所谓的React模拟事件系统。
  • 在 HTML 中,事件名称使用小写,而 React 中使用驼峰命名。
  • 在 HTML 中,阻止事件的默认行为使用 return false,而 React 中必须调用 preventDefault
3.react组件中怎么做事件代理?他的原理是什么
4.react高阶组件、render props、hooks有什么区别,为什么不要迭代
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值