react面试总结

178 阅读6分钟
react的核心有哪些?

state定义数据 生命周期 组件通信 路由 非兄弟之间通信 fiber

1 怎么修改在state定义的值?

直接使用this.setState()进行修改,不能像vue那样直接修改

2 react中有指令吗?

没有 如果需要使用循环 可以使用map方法循环出多个元素

3 react中的生命周期?

3.1 初始化:初始进入页面 → constructor → componentWillMount → render → componentDidMount → componentWillUnmount;

3.2 更新:setState → componentWillReceiveProps → shouldComponentUpdate → componentWillUpdate → render → componentDidUpdate → componentWillUnmount。

4 父子组件生命周期
  • 页面初次渲染:constructor-->componentWillMount-->render ----> son-constructor-->son-componentWillMount-->son-render-->son-componentDidMount -->componentDidMount
  • 更新状态:father-shouldComponentUpdate--->father-componentWillUpdate--->father-render-->son-componentWillReceiveProps-->son-componentWillUpdate-->son-render--->son-componentDidUpdate--->father-componentDidUpdate**
5 组件间通信
  • 5.1 父组件向子组件通讯: 父组件可以向子组件通过传<FSon msg={this.state.message} />的方式,向子组件进行通讯
        5.1.1 类组件使用 this.props 获取 props 对象 默认值使用static defaultProps = {}或者类名.defaultProps = {},类型使用static propTypes = {}
        5.1.2 函数组件直接在参数中获取 props 对象,默认值使用组件名.defaultProps = {}定义默认值,类型使用组件名.propTypes = {}给组件添加校验规则,注意这里需要提前安装prop-types
        
  • 5.2 子 组件向父组件通讯: props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中
  • 5.3 兄弟组件通信: 找到这两个兄弟节点共同的父节点,结合上面两种方式由父节点转发信息进行通信
  • 5.4 跨层级通信: Context设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言,对于跨越多层的全局数据通过Context通信再适合不过
  • 5.5 布订阅模式: 发布者发布事件,订阅者监听事件并做出反应,我们可以通过引入event模块进行通信
  • 5.6 局状态管理工具: 借助Redux或者Mobx等全局状态管理工具进行通信,这种工具会维护一个全局状态中心Store,并根据不同的事件产生新的状态
6 插槽(slot)props.children接受数据,定义数据使用下面3种方式

6.1 使用children实现插槽
<NavBar>
<button>按钮</button> <h2>哈哈哈</h2> <i>斜体文本</i>
</NavBar>
6.2 使用props实现插槽
<NavBarTwo leftSlot={btn} centerSlot={<h2>呵呵呵</h2>} rightSlot={<i>斜体2</i>} />
6.3 作用域插槽
<TabControl
tabList={tabList} tabClick={i => this.setState({ tabIndex: i })} itemType={item => this.getTabItem(item)} />

7 react路由

在react-router6包含两种路由:BrowserRouter和HashRouter,BrowserRouter使用history模式;而HashRouter从字面上就能看出它使用的是hash模式。

    我们在配置路由之前,首先要做的是选定当前项目的路由模式 BrowserRouter 或 HashRouter。一旦选定后,我们要用此组件去包裹整个项目的根组件(一般是App组件)如下所示:

import { BrowserRouter } from 'react-router-dom';
...

root.render(
      <BrowserRouter>
          <App />
      </BrowserRouter>
)

image.png

7.1 路由跳转:Link和NavLink

    在上面一part中,我们已经配置了一个简单的路由映射关系。但有小伙伴发现了问题,我们在进行跳转时都是手动去地址栏更改路径从而更换我们要展示的页面内容。这种方式在实际开发中显示是不现实的。对此,router6给我们提供了Link 和 NavLink 组件(这些组件最终都会被渲染成a元素)来帮助我们进行路由跳转。

7.2 属性介绍:

这两个组件主要包含两个属性:to属性和replace属性。

  • to属性: 用来设置跳转到哪个路径,相当于是push操作;
  • replace属性:和to类似,也会跳转到目标路径,但其执行的是replace操作;
7.3 Link组件代码实操:

    知道了组件的内部属性后,下面我们就来编写一段代码再深入感受下Link组件。

import { useEffect } from "react";
import { Routes, Route, Link } from "react-router-dom";
import Home from "@/pages/home/home";
import Login from "@/pages/login/login";
import NotFound from "@/components/404/notFound";
import "./index.less";

function App() {
 
  return (
    <div className="App">
      <div className="jumpBtn">
        <Link to="/">跳转Home</Link>&nbsp;
        <Link to="/login">
          跳转Login
        </Link>
        &nbsp;
        <Link to="/abc" replace={true}>
          跳转notFound
        </Link>
      </div>
      <div className="header">这是固定不变的header,下面是会改变的content</div>
      <div className="content">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/login" element={<Login />} />
          <Route path="*" element={<NotFound />} />
        </Routes>
      </div>
    </div>
  );
}

export default App;

to属性 和 replace属性 区别:

    跳转notFound时,我们设置了replace属性,也就是说我们/abc路径会把路由栈里当前路由替换掉。对应这里的操作是:我们依次点击跳转 Home --> 跳转Login --> 跳转notFound ; 路由栈里的变化是 / --> /login --> /abc 但由于我们设置跳转notFound的replace属性为true,所以实际上路由栈的变化是 / --> /login (当点击跳转notFound时 /login 被替换成了 /abc )

    这里咱又重申了to 和 replace的区别,目的是在于给xdm加深下印象,咱不能在项目里无脑push或者to,因为有些情况是需要用replace来代替当前路由路径的。

7.4 NavLink组件介绍:

    介绍完了Link组件,接下来我们就来介绍下NavLink,其实router6里的NavLink就是Link组件的样式增强版,它与Link的用法基本,只不过就是多了几个属性可以让我们进行设置样式,并且当前选中的NavLink组件上会多出一个active类名:

  • style 属性:接收一个函数,函数接收一个对象,包含isActive属性,表示当前是否被选中;
  • className 属性:接收一个函数,函数接收一个对象,包含isActive属性,表示当前是否被选中;

    好了,既然清楚了NavLink的额外属性后,现在我们来实现一个小需求:当选中标签时,标签的文字要显示成蓝色!

    现在我们App组件里的Link部分替换成NavLink:

  <div className="jumpBtn">
        <NavLink to="/"> 跳转Home </NavLink>
        &nbsp; 
        <NavLink  to="/login" > 跳转Login </NavLink>
        &nbsp; 
        <NavLink to="/abc" > 跳转notFound  </NavLink>
   </div>
8 Redux

使用步骤

  • 使用createStore定义个store
  • 使用store.dispatch 差法action里面的方法
  • 通过getState获取到store里面所有的值
  • redux内部不支持自动更新,需要通过subscribeAPI监听redux中状态变化
  • store.subscribe(() => { this.setState({ count: store.getState().count }); });

image

  • 页面上用户通过 dispatch 方法触发一个 Action: dispatch(Action)
  • Store 接收到 Action
  • Store 调用 Reducer 函数, 并将 Action 和当前状态作为参数传递给它
  • Reducer 函数根据 Action 类型执行相应的处理, 并返回新的状态
  • Store 更新状态, 并通知所有订阅状态的组件(视图)
  • 组件(视图)收到通知, 获取新状态, 重新渲染

redux内部不支持自动更新,需要通过subscribeAPI监听redux中状态变化,只有变化,就需要重新调用render

jsx
复制代码
componentDidMount() {
    store.subscribe(() => {
      this.forceUpdate();
    });
}