react 强制刷新

component.forceUpdate() 一个不罕用的生命周期办法, 它的作用就是强制刷新

官网解释如下

默认状况下,当组件的 state 或 props 发生变化时,组件将从新渲染。如果 render() 办法依赖于其余数据,则能够调用 forceUpdate() 强制让组件从新渲染。

调用 forceUpdate() 将以致组件调用 render() 办法,此操作会跳过该组件的 shouldComponentUpdate()。但其子组件会触发失常的生命周期办法,包含 shouldComponentUpdate() 办法。如果标记发生变化,React 仍将只更新 DOM。

通常你应该防止应用 forceUpdate(),尽量在 render() 中应用 this.props 和 this.state。

shouldComponentUpdate 在初始化 和 forceUpdate 不会执行

React 父组件如何调用子组件中的办法?

  1. 如果是在办法组件中调用子组件(>= 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>  );};
  1. 如果是在类组件中调用子组件(>= 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。这种机制能够让咱们扭转数据流,实现如异步actionaction 过滤,日志输入,异样报告等性能
  • 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 的作用是什么

  • RefsReact 提供给咱们的平安拜访 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:1b: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 只会匹配雷同 classcomponent(这外面的class指的是组件的名字)
  • 合并操作,调用 componentsetState 办法的时候, React 将其标记为 - dirty.到每一个事件循环完结, React 查看所有标记 dirtycomponent从新绘制.
  • 抉择性子树渲染。开发人员能够重写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,可能使咱们的代码放弃更多功能,还能够防止过多应用基于类的组件。