react 强制刷新
component.forceUpdate() 一个不罕用的生命周期办法, 它的作用就是强制刷新
官网解释如下
默认状况下,当组件的 state 或 props 发生变化时,组件将从新渲染。如果 render() 办法依赖于其余数据,则能够调用 forceUpdate() 强制让组件从新渲染。
调用 forceUpdate() 将以致组件调用 render() 办法,此操作会跳过该组件的 shouldComponentUpdate()。但其子组件会触发失常的生命周期办法,包含 shouldComponentUpdate() 办法。如果标记发生变化,React 仍将只更新 DOM。
通常你应该防止应用 forceUpdate(),尽量在 render() 中应用 this.props 和 this.state。
shouldComponentUpdate 在初始化 和 forceUpdate 不会执行
React 父组件如何调用子组件中的办法?
- 如果是在办法组件中调用子组件(>= react@16.8),能够应用 useRef 和
useImperativeHandle
:
const { forwardRef, useRef, useImperativeHandle } = React;const Child = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ getAlert() { alert("getAlert from Child"); } })); return <h1>Hi</h1>;});const Parent = () => { const childRef = useRef(); return ( <div> <Child ref={childRef} /> <button onClick={() => childRef.current.getAlert()}>Click</button> </div> );};
- 如果是在类组件中调用子组件(
>= react@16.4
),能够应用 createRef:
const { Component } = React;class Parent extends Component { constructor(props) { super(props); this.child = React.createRef(); } onClick = () => { this.child.current.getAlert(); }; render() { return ( <div> <Child ref={this.child} /> <button onClick={this.onClick}>Click</button> </div> ); }}class Child extends Component { getAlert() { alert('getAlert from Child'); } render() { return <h1>Hello</h1>; }}
React中Diff算法的原理是什么?
原理如下。
(1)节点之间的比拟。
节点包含两种类型:一种是 React组件,另一种是HTML的DOM。
如果节点类型不同,按以下形式比拟。
如果 HTML DOM不同,间接应用新的替换旧的。如果组件类型不同,也间接应用新的替换旧的。
如果 HTML DOM类型雷同,按以下形式比拟。
在 React里款式并不是一个纯正的字符串,而是一个对象,这样在款式产生扭转时,只须要扭转替换变动当前的款式。批改完以后节点之后,递归解决该节点的子节点。
如果组件类型雷同,按以下形式比拟。
如果组件类型雷同,应用 React机制解决。个别应用新的 props替换旧的 props,并在之后调用组件的 componentWillReceiveProps办法,之前组件的 render办法会被调用。
节点的比拟机制开始递归作用于它的子节点。
(2)两个列表之间的比拟。
一个节点列表中的一个节点产生扭转, React无奈很妤地解决这个问题。循环新旧两个列表,并找出不同,这是 React惟一的解决办法。
然而,有一个方法能够把这个算法的复杂度升高。那就是在生成一个节点列表时给每个节点上增加一个key。这个key只须要在这一个节点列表中惟一,不须要全局惟一。
(3)取舍
须要留神的是,下面的启发式算法基于两点假如。
类型相近的节点总是生成同样的树,而类型不同的节点也总是生成不同的树
能够为屡次 render都体现稳固的节点设置key。
下面的节点之间的比拟算法基本上就是基于这两个假如而实现的。要进步 React利用的效率,须要依照这两点假如来开发。
传入 setState 函数的第二个参数的作用是什么?
该函数会在 setState
函数调用实现并且组件开始重渲染的时候被调用,咱们能够用该函数来监听渲染是否实现:
this.setState( { username: 'tylermcginnis33' }, () => console.log('setState has finished and the component has re-rendered.'))
this.setState((prevState, props) => { return { streak: prevState.streak + props.count }})
redux有什么毛病
- 一个组件所须要的数据,必须由父组件传过来,而不能像
flux
中间接从store
取。 - 当一个组件相干数据更新时,即便父组件不须要用到这个组件,父组件还是会从新
render
,可能会有效率影响,或者须要写简单的shouldComponentUpdate
进行判断。
redux中间件
中间件提供第三方插件的模式,自定义拦挡action
->reducer
的过程。变为action
->middlewares
->reducer
。这种机制能够让咱们扭转数据流,实现如异步action
,action
过滤,日志输入,异样报告等性能
redux-logger
:提供日志输入redux-thunk
:解决异步操作redux-promise
:解决异步操作,actionCreator
的返回值是promise
参考 前端进阶面试题具体解答
组件更新有几种办法
- this.setState() 批改状态的时候 会更新组件
- this.forceUpdate() 强制更新
- 组件件render之后,子组件应用到父组件中状态,导致子组件的props属性产生扭转的时候 也会触发子组件的更新
什么是 React的refs?为什么它们很重要
refs容许你间接拜访DOM元素或组件实例。为了应用它们,能够向组件增加个ref属性。
如果该属性的值是一个回调函数,它将承受底层的DOM元素或组件的已挂载实例作为其第一个参数。能够在组件中存储它。
export class App extends Component { showResult() { console.log(this.input.value); } render() { return ( <div> <input type="text" ref={(input) => (this.input = input)} /> <button onClick={this.showResult.bind(this)}>展现后果</button> </div> ); }}
如果该属性值是一个字符串, React将会在组件实例化对象的refs属性中,存储一个同名属性,该属性是对这个DOM元素的援用。能够通过原生的 DOM API操作它。
export class App extends Component { showResult() { console.log(this.refs.username.value); } render() { return ( <div> <input type="text" ref="username" /> <button onClick={this.showResu1t.bind(this)}>展现后果</button> </div> ); }}
React 中 refs 的作用是什么
Refs
是React
提供给咱们的平安拜访DOM
元素或者某个组件实例的句柄- 能够为元素增加
ref
属性而后在回调函数中承受该元素在DOM
树中的句柄,该值会作为回调函数的第一个参数返回
hooks 为什么不能放在条件判断里
以 setState 为例,在 react 外部,每个组件(Fiber)的 hooks 都是以链表的模式存在 memoizeState 属性中
update 阶段,每次调用 setState,链表就会执行 next 向后挪动一步。如果将 setState 写在条件判断中,假如条件判断不成立,没有执行外面的 setState 办法,会导致接下来所有的 setState 的取值呈现偏移,从而导致异样产生。
useEffect(fn, []) 和 componentDidMount 有什么差别
useEffect
会捕捉props
和 state。所以即使在回调函数里,你拿到的还是初始的 props 和 state。如果想得到“最新”的值,能够应用 ref。
生命周期调用办法的程序是什么?
React生命周期分为三大周期,11个阶段,生命周期办法调用程序别离如下。
(1)在创立期的五大阶段,调用办法的程序如下。
- getDetaultProps:定义默认属性数据。
- getInitialState:初始化默认状态数据。
- component WillMount:组件行将被构建。
- render:渲染组件。
- componentDidMount:组件构建实现
(2)在存在期的五大阶段,调用办法的程序如下。
- componentWillReceiveProps:组件行将接管新的属性数据。
- shouldComponentUpdate:判断组件是否应该更新。
- componnent WillUpdate:组件行将更新。
- render:渲染组件。
- componentDidUpdate:组件更新实现。
(3)在销毁期的一个阶段,调用办法 componentWillUnmount,示意组件行将被销毀。
react性能优化计划
- 重写
shouldComponentUpdate
来防止不必要的dom操作 - 应用
production
版本的react.js
- 应用
key
来帮忙React
辨认列表中所有子组件的最小变动
这三个点(...)在 React 干嘛用的?
...
在React(应用JSX)代码中做什么?它叫什么?
<Modal {...this.props} title='Modal heading' animation={false}/>
这个叫扩大操作符号或者开展操作符,例如,如果this.props
蕴含a:1
和b:2
,则
<Modal {...this.props} title='Modal heading' animation={false}>
等价于上面内容:
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>
扩大符号不仅实用于该用例,而且对于创立具备现有对象的大多数(或全副)属性的新对象十分不便,在更新state
咱们就常常这么做:
this.setState((prevState) => { return { foo: { ...prevState.foo, a: "updated" } };});
diff算法?
- 把树形构造依照层级合成,只比拟同级元素。
- 给列表构造的每个单元增加惟一的
key
属性,不便比拟。 React
只会匹配雷同class
的component
(这外面的class
指的是组件的名字)- 合并操作,调用
component
的setState
办法的时候,React
将其标记为 -dirty
.到每一个事件循环完结,React
查看所有标记dirty
的component
从新绘制. - 抉择性子树渲染。开发人员能够重写
shouldComponentUpdate
进步diff
的性能
在结构函数调用 super
并将 props
作为参数传入的作用是啥?
在调用 super()
办法之前,子类构造函数无奈应用this
援用,ES6 子类也是如此。将 props
参数传递给 super()
调用的次要起因是在子构造函数中可能通过this.props
来获取传入的 props
。
传递 props
class MyComponent extends React.Component { constructor(props) { super(props); console.log(this.props); // { name: 'sudheer',age: 30 } }}
没传递 props
class MyComponent extends React.Component { constructor(props) { super(); console.log(this.props); // undefined // 然而 Props 参数依然可用 console.log(props); // Prints { name: 'sudheer',age: 30 } } render() { // 构造函数内部不受影响 console.log(this.props); // { name: 'sudheer',age: 30 } }}
下面示例揭示了一点。props
的行为只有在构造函数中是不同的,在构造函数之外也是一样的。
这段代码有什么问题?
class App extends Component { constructor(props) { super(props); this.state = { username: "有课前端网", msg: " ", }; } render() { return <div> {this.state.msg}</div>; } componentDidMount() { this.setState((oldState, props) => { return { msg: oldState.username + " - " + props.intro, }; }); }}
render ( < App intro=" 前端技术业余学习平台"></App>,ickt )
在页面中失常输入“有课前端网-前端技术业余学习平台”。然而这种写法很少应用,并不是罕用的写法。React容许对 setState办法传递一个函数,它接管到先前的状态和属性数据并返回一个须要批改的状态对象,正如咱们在下面所做的那样。它岂但没有问题,而且如果依据以前的状态( state)以及属性来批改以后状态,举荐应用这种写法。
React- Router有几种模式?
有以下几种模式。
HashRouter,通过散列实现,路由要带#。
BrowerRouter,利用HTML5中 history API实现,须要服务器端反对,兼容性不是很好。
如何应用4.0版本的 React Router?
React Router 4.0版本中对 hashHistory做了迁徙,执行包装置命令 npm install react-router-dom后,依照如下代码进行应用即可。
import { HashRouter, Route, Redirect, Switch } from " react-router-dom";class App extends Component { render() { return ( <div> <Switch> <Route path="/list" componen t={List}></Route> <Route path="/detail/:id" component={Detail}> {" "} </Route> <Redirect from="/ " to="/list"> {" "} </Redirect> </Switch> </div> ); }}const routes = ( <HashRouter> <App> </App> </HashRouter>);render(routes, ickt);
React 中的 useState()
是什么?
上面阐明useState(0)
的用处:
const [count, setCounter] = useState(0);const [moreStuff, setMoreStuff] = useState();const setCount = () => { setCounter(count + 1); setMoreStuff();};
useState
是一个内置的 React Hook。useState(0)
返回一个元组,其中第一个参数count
是计数器的以后状态,setCounter
提供更新计数器状态的办法。
咱们能够在任何中央应用setCounter
办法更新计数状态-在这种状况下,咱们在setCount
函数外部应用它能够做更多的事件,应用 Hooks,可能使咱们的代码放弃更多功能,还能够防止过多应用基于类的组件。