React面試總結(jié)

1.jsx基本使用

  • 變量,表達(dá)式
    在render函數(shù)里使用 {this.state.xxx}表達(dá)式獲取變量
  • class style寫法是
//如果要插入一段原生html,可以使用
</p>
  const ralHtml = `<span>asdasdasd</span><pdangerslySetInnerHTML={ralHtml}>
</p>`
  • 子元素和組件
    條件判斷
    1.if else
    2.三元表達(dá)式
    3.邏輯運(yùn)算符&& ||

  • 渲染列表
    1.map
    2.key

2.事件

1.bind this 性能優(yōu)化小知識(shí)點(diǎn),可以在constructor里面修改函數(shù)this的指向

constructor(props) {
  super(props)
  this.getFirstRequest = this.getFirstRequest.bind(this)
}

或者使用靜態(tài)方法(箭頭函數(shù),this指向當(dāng)前實(shí)例)

//改變狀態(tài)前后都想做一些事情:
this.setState((prevState)=>{
    // prevState:是舊值
    console.log("prevState",prevState)
    return {
        age:15
    }
},()=>{
    // this.state:就是新值。
    console.log(this.state.age);
}); 

2.關(guān)于event參數(shù)
3.傳遞自定義參數(shù)

3.react事件和dom事件

react中的event是syntheticEvent(合成事件),模擬出來DOM事件所有能力
event.nativeEvent是原生事件對象
所有的事件,都被掛載到doucument上(react16),
react17開始事件綁定到root上
和dom事件不一樣和vue事件也不一樣

//傳遞參數(shù)
clickHandle(id,title,event){
  //最后追加一個(gè)參數(shù),即可接收event
}

4.react表單知識(shí)點(diǎn)串講

1.受控組件

render(){
  return (<div>
          <p>{this.state.name}</p>
          <input value={this.state.name} onchange=(this.changeValue)/>
    </div>
  )
}
//textArea 這些的值,要用vue,而不是
<textArea>{this.state.value}</textArea>

5.react父子組件通訊

1.props傳遞數(shù)據(jù)
2.props傳遞函數(shù)
3.props類型檢查
狀態(tài)提升,意思是把數(shù)據(jù)放在在高一層的組件,高層組件來做數(shù)據(jù)跟改和數(shù)據(jù)分發(fā),子組件只用來渲染

6.setState為何使用不可變值

setState
1.不可變值
不要直接操作不可變值,要用this.setState()
不能對this.state.arr直接使用push pop splice等,這樣違反不可變值
不僅數(shù)組,object也是一樣,最好的做法就是生成一份副本,再對副本做修改,然后使用this.setState()進(jìn)行設(shè)置
在生命周期shouldComponentUpdate會(huì)有影響

//不要這樣使用
this.setState({list:this.state.list.splice(0,3)})

2.什么建議傳遞給setState函數(shù)的參數(shù)是回調(diào)函數(shù)而不是對象?
因?yàn)椋瑃his.setState()函數(shù)內(nèi)部是異步執(zhí)行的。

this.setState({
     msg:"hello"
});
console.log(this.state.msg);// 這個(gè)值不是hello

換一種寫法

this.setState({
count:this.state.count+1
},()=>{
//這里獲取的是改變的最新的值
console.log(this.state.count)
})
//這里是之前未改變的值
console.log(this.state.count)

setState直接使用是異步的,在setTimeout和自定義dom事件中使用是同步的
3.可能會(huì)被合并
傳入對象,會(huì)被合并,執(zhí)行結(jié)果只一次 +1,類似于(Object.assgin)

this.setState({
count:this.state.count+1
})
this.setState({
count:this.state.count+1
})
this.setState({
count:this.state.count+1
})
//相當(dāng)于只執(zhí)行了一次
this.setState({
count:0+1
})

傳入函數(shù),不會(huì)被合并,執(zhí)行結(jié)果+3

this,.setState((prevState,props)=>{
  return{
  count:prevState.count+1
  }
})
this,.setState((prevState,props)=>{
  return{
  count:prevState.count+1
  }
})
this,.setState((prevState,props)=>{
  return{
  count:prevState.count+1
  }
})
//結(jié)果會(huì)是3,6,9依次往上疊加,

7.組件生命周期

  • 1 React16
// 組件將要掛載
constructor(props){
  super(props)
}
componentWillMount(){
  console.log("Count---componentWillMount")
} 
// 渲染組件  常用
render(){
  return(
    <div></div>
  )
}
//  組件掛在完畢的鉤子  常用
componentDidMount(){
  console.log("Count---componentDidMount")
}
// 組件將要卸載  常用
componentWillUnmount(){
  console.log("Count---componentWillUnmount")
}
// 控制組件更新的閥門 返回true繼續(xù)  false 結(jié)束
shouldComponentUpdate (){
  console.log("Count---shouldComponentUpdate")
  return true
}
// 組件將要更新
componentWillUpdate(){
  console.log("Count---componentWillUpdate")
}
// 組件更新完成
componentDidUpdate(){
  console.log("Count---componentDidUpdate")
}
react生命周期(16).png
  • React17
// 構(gòu)造器
constructor(props){
  super(props)
}
//  若 state 的值在任何時(shí)候都取決于 props
static getDerivedStateFromProps(props,state){
  console.log("Count---getDerivedStateFromProps",props,state)
  return null
}
// 在更新之前獲取快照
getSnapshotBeforeUpdate(snapshot){
  console.log("Count---getSnapshotBeforeUpdate",snapshot)
  return "test"
}
// 渲染組件  常用
render(){
  return(
     <div></div>
  )
}
//  組件掛在完畢的鉤子  常用
componentDidMount(){
  console.log("Count---componentDidMount")
}   
// 組件將要卸載 常用
componentWillUnmount(){
  console.log("Count---componentWillUnmount")
}
// 控制組件更新的閥門 返回true繼續(xù)  false 結(jié)束
shouldComponentUpdate (){
  console.log("Count---shouldComponentUpdate")
  return true
}
// 組件更新完成
componentDidUpdate(preProps,preState,snapshotVlaue){
  console.log("Count---componentDidUpdate",preProps,preState,snapshotVlaue)
}

react生命周期(17).png

8.react函數(shù)組件和class組件的區(qū)別

1.純函數(shù),輸入props,輸入jsx
2.沒有實(shí)例,沒有生命周期,沒有state
3.不能擴(kuò)展其他方法

9.非受控組件

1.ref(三種方式 字符串 函數(shù)回調(diào) create_ref)
2.defaultValue defaultChecked
3手動(dòng)操作DOM元素
非受控組件
必須手動(dòng)操作DOM元素,setState實(shí)現(xiàn)不了
文件上傳
某些富文本編輯器,需要傳入DOM元素

10.portals 傳送門

組件默認(rèn)會(huì)按照既定層次嵌套渲染
如何讓組件渲染到父組件以外
應(yīng)用場景: 對話框、懸浮卡以及提示框:
overflow:hidden(父級設(shè)置了BFC)
父組件z-index值太小
fixed需要放在body第一層級

render(){
  //正常使用
return <div class="modal">
    {this.props.children}
</div>
}
//使用Portals渲染到body上
return ReactDom.createPortal(
<div class="modal">
    {this.props.children}
</div>,document.body //后面這個(gè)document.body值的意思是渲染到body里面
)

11.react Context

主要用于設(shè)置公共信息(語言,主題)

//創(chuàng)建Context默認(rèn)值
  const ThemeContext = React.createContext('light')
  //在最外層的父組件 渲染時(shí)用<ThemeContext.Provider value={this.state.theme}>包裹
render(){
return 
<ThemeContext.Provider value={this.state.theme}>
//里面是一些子組件
<ThemedBUtton />
<ThemeContext.Provider>
}
//子組件獲取context值(class組件)
class ThemedBUtton extends React.Component{
render(){
const theme = this.context//react會(huì)往上找最近的provider
return <div>
    <p>{theme} </p>
</div>
  }
}
themedButton.contextType = ThemeContext //指定conterxtType

//也可以寫成
static contextType = themeContext
//函數(shù)組件獲取
function theLinkl(props){
return <ThemeContext.Consumer>
{value => <p>link's theme is {value}</p>}
</ThemeContext.Consumer>
}

12.異步組件
import()
react.lazy
react.suspense

//異步加載當(dāng)前組件
const ContextDemo= React.lazy(()=>import('./ContextDemo'))
class App extends React.Component{
constructor(props){
  super(props)
  }
render(){
  return <div>  
  <React.Suspense fallBack={<div>Loading...</div}
      <ContextDemo/>
</React.Suspense>
</div>
}
}

13.性能優(yōu)化

  • shouldComponentUpdate(簡稱SCU),必須配合不可變值使用
    scu基本用法
shouldComponentUpdate(nextProps,nextState){
  if(nextState.count !== this.state.count){
    return true //刻意渲染
  }
  return false
}
  • PureComponent(純組件)和React.memo
    純組件其實(shí)也是scu中進(jìn)行了淺比較,只比對了第一層是否一樣
    函數(shù)組件中的pureComponent memo
    -不可變值immutable.js
    1.徹底擁抱不可變值
    2.基于共享數(shù)據(jù)(不是深拷貝),速度好
    3.有一定的學(xué)習(xí)成本和遷移成本,按需使用

14.react高階組件

HOC

//高階組件不是一種功能,而是一種模式
const HOCFactory = (COmponent)=>{
  class HOC extends React.Component{
    //在此定義多個(gè)組件的公共邏輯
  render(){
    return <Component {...this.props} />//返回拼裝結(jié)果
   }
  }
  return HOC
}
const EnhancedComponent1 = HOCFactory(WrappedComponent1)
const EnhancedComponent2 = HOCFactory(WrappedComponent2)
  • HOC vs Render Props
    1.HOC:模式簡單,但會(huì)增加組件層級
    2.render props:代碼簡潔,學(xué)習(xí)成本較高
    3.按需使用
    在react中實(shí)現(xiàn)公共邏輯的抽離,使用HOC或者render props

15.Redux使用

1.和vuex作用相同,但比Vuex學(xué)習(xí)成本高
2.不可變值,純函數(shù)
3.面試???/p>

基本概念

  • 1.store state
  1. 將state、action、reducer聯(lián)系在一起的對象
  2. 如何得到此對象?
  1. import {createStore} from 'redux'
  2. import reducer from './reducers'
  3. const store = createStore(reducer)
  1. 此對象的功能?
  1. getState(): 得到state
  2. dispatch(action): 分發(fā)action, 觸發(fā)reducer調(diào)用, 產(chǎn)生新的state
  3. subscribe(listener): 注冊監(jiān)聽, 當(dāng)產(chǎn)生了新的state時(shí), 自動(dòng)調(diào)用
  • 2.action
  1. 動(dòng)作的對象
  2. 包含2個(gè)屬性

type:標(biāo)識(shí)屬性, 值為字符串, 唯一, 必要屬性
data:數(shù)據(jù)屬性, 值類型任意, 可選屬性

  1. 例子:
{ type: 'ADD_STUDENT',data:{name:  'tom',age:18} }

3.reducer

  1. 用于初始化狀態(tài)、加工狀態(tài)。
  2. 加工時(shí),根據(jù)舊的state和action, 產(chǎn)生新的state的純函數(shù)。
  • 單向數(shù)據(jù)流
    dispatch(action)
    reducer -> newState(不可變值)
    subscribe 觸發(fā)通知
  • react-redux
    Provider
    connect
    mapStateToProps mapDispatchToProps
    在需要使用的index.js文件里面引入Provider
//使用Provider整體傳入store對象
import {Privder} from 'react-redux'
import todoApp from './reducers'
import App from './component/App'
let store = createStore(todoApp)
export store = function(){
  return <Provider store={store}> 
  <App />
</Provider>
}
//需要消費(fèi)store的子組件里面需要調(diào)用一下connect方法
AddTodo = connect()(AddTodo)
export default AddTodo
//調(diào)用connect()后dispatch已經(jīng)被注入到該組件中
//dispatch一個(gè)action到 effects =>reducer(不可變值)=>返回新的值=>store修改=>觸發(fā)訂閱跟新數(shù)據(jù)=>頁面刷新

  • 異步action
    首先在創(chuàng)建store的時(shí)候要引入
import {createStore,applyMiddleWare} from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers/index'
const store = createStrore(rootReducer,applyMiddleWare(thunk ))
//在使用action 的地方 以前是返回一個(gè)對象,現(xiàn)在返回一個(gè)函數(shù)
  • 中間件
    中間件原理,大致就是把當(dāng)前的dispatch做了下改造,先把當(dāng)前的disptch用一個(gè)
let next = dispatch
console.log(1)
next()
console.log(2)

16.react-router路由模式

1.hash模式(默認(rèn) 兼容性更強(qiáng))
2.h5history模式(更美觀)
3.后者需要后端支持,因此無特殊需求選擇前者

import{hashRouter as Router,Switch,Route} from 'react-router-dom'
//BromserRouter as Router
function RouterComponent(){
  return(
    <router>
      <Switch>
          <route path="*">
          //這里面包裹組件
          </route>
      </Switch>
    </router>
  )
}

17jsx本質(zhì)

通過createelement函數(shù) 第一個(gè)參數(shù)是tag,第二個(gè)參數(shù)是屬性也就是一個(gè)對象,沒有的話傳入null,第三個(gè)參數(shù)可以是數(shù)組,數(shù)組里面繼續(xù)是createelement函數(shù)對應(yīng)的子元素,依次。也可以打散挨個(gè)傳入。最終返回一個(gè)vnode 在通過patch渲染

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目標(biāo) 掌握類組件的定義和使用; 掌握 React 組件間通信的方式; 掌握類組件的生命周期。 內(nèi)容 在 React...
    magic_pill閱讀 338評論 0 0
  • 性能優(yōu)化 性能優(yōu)化,永遠(yuǎn)是面試的重點(diǎn),性能優(yōu)化對于 React 更加重要 在頁面中使用了setTimout()、a...
    Actoress閱讀 1,700評論 0 5
  • jsx基本使用 變量,表達(dá)式在render函數(shù)里使用 {this.state.xxx}表達(dá)式獲取變量 class ...
    懵逼貓9527閱讀 384評論 0 2
  • 作為一個(gè)合格的開發(fā)者,不要只滿足于編寫了可以運(yùn)行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個(gè)周閱讀 8,675評論 1 33
  • 常見面試題:1.React組件如何通訊?2.JSX本質(zhì)是什么?3.context是什么?有何用途?4.should...
    洛珎閱讀 856評論 0 2

友情鏈接更多精彩內(nèi)容