最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue和react中props變化后如何修改state

 更新時間:2022年08月08日 09:56:53   作者:前端精髓  
這篇文章主要介紹了vue和react中props變化后如何修改state,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

vue和react中props變化后修改state

如果只想在 state 更改時重新計算某些數(shù)據(jù),比如搜索框案例。

vue

<template>
  <div>
  	<input type="text" v-model="filterText">
    <ul>
      <li v-for="item in filteredList" :key="item.id">
        {{ item.text }}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  props: {
    list: {
      type: Array,
      default: () => ([])
    }
  },
  data () {
    return {
      filterText: ''
    }
  },
  computed: {
    filteredList () {
      return this.list.filter(item => item.text.includes(this.filterText))
    }
  }
}
</script>

react

import React, { PureComponent } from 'react';
class Example extends PureComponent {
  state = {
    filterText: ''
  };
  handleChange = event => {
    this.setState({
      filterText: event.target.value
    })
  }
  render() {
    const filteredList = this.filter(this.props.list, this.state.filterText)
    return (
      <>
        <input
          type="text"
          onChange={this.handleChange}
          value={this.state.filterText} />
        <ul>
          {
            filteredList.map(
              item => <li key={item.id}>{item.text}</li>
            )
          }
        </ul>
      </>
    );
  }
}

如果你想在 prop 更改時“重置”某些 state,比如隨機(jī)默認(rèn)值案例

vue

Vue提供了一種更通用的方式來觀察和響應(yīng)Vue實例上的數(shù)據(jù)變動:偵聽屬性 watch。

<template>
  <div>
    <input type="text" v-model="text">
  </div>
</template>
<script>
export default {
  props: {
    email: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      text: ''
    }
  },
  watch: {
    email: {
      immediate: true,
      handler (value) {
        this.text = value
      }
    }
  }
}
</script>

react

React生命周期 getDerivedStateFromProps 會在調(diào)用 render 方法之前調(diào)用,并且在初始掛載及后續(xù)更新時都會被調(diào)用。它應(yīng)返回一個對象來更新 state,如果返回 null 則不更新任何內(nèi)容。

父組件重新渲染時觸發(fā),請注意,不管原因是什么,都會在每次渲染前觸發(fā)此方法。

class Example extends Component {
  state = {
    text: ''
  };
  handleChange = (event) => {
    this.setState({
      text: event.target.value
    })
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.email !== nextProps.email) {
      return {
        text: nextProps.email,
        email: nextProps.email
      }
    }
    return {text: prevState.text}
  }
  render() {
    return (
      <>
        <input
          type="text"
          onChange={this.handleChange}
          value={this.state.text} />
      </>
    );
  }
}

改進(jìn)

直接復(fù)制 prop 到 state 是一個非常糟糕的想法。這兩者的關(guān)鍵在于,任何數(shù)據(jù),都要保證只有一個數(shù)據(jù)來源,而且避免直接復(fù)制它。

vue

<template>
  <div>
    <input type="text" :value="value" @input="handleInput">
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  methods: {
    handleInput (e) {
      this.$emit('input', e.target.value)
    }
  }
}
</script>
<template>
  <div id="app">
    <Example v-model="email"/>
    <button @click="handleClick">默認(rèn)值</button>
  </div>
</template>
<script>
import Example from './components/Example.vue'
export default {
  components: {
    Example
  },
  data () {
    return {
      email: ''
    }
  },
  methods: {
    handleClick () {
      this.email = String(Math.random())
    }
  }
}
</script>

react

function Example (props) {
  return <input onChange={props.onChange} value={props.email} />;
}
class App extends React.Component {
  state = {
    email: ''
  }
  handleClick = () => {
    this.setState({
      email: String(Math.random())
    })
  }
  handleChange = (event) => {
    this.setState({
      email: event.target.value
    })
  }
  render() {
    return (
      <>
        <Example email={this.state.email} onChange={this.handleChange} />
        <div>
          <button onClick={this.handleClick}>默認(rèn)值</button>
        </div>
      </>
    );
  }
}

react改變state必須知道的知識點(diǎn)

react可以通過this.state.xx的方式直接獲取state,但是當(dāng)我們修改state的時候,往往有許多的坑。

1.不能直接修改state

組件修改state,并不會重新觸發(fā)render。例如:

?//錯誤
this.state.title='attend';
//正確
this.setState({title:'attend'});

2.state的更新是異步的

調(diào)用setState時,組件state并不會立即改變,只是把要修改的狀態(tài)放入事件隊列當(dāng)中,為了彌補(bǔ)這個問題,使用另一種 setState() 的形式,接受一個函數(shù)。

這個函數(shù)將接收前一個狀態(tài)作為第一個參數(shù),應(yīng)用更新時的 props 作為第二個參數(shù),代碼如下:

//正確
this.setState((prevState, props)=>({
?? ?counter: prevState.counter + 1
}))

3.state的更新是一個合并的過程

當(dāng)調(diào)用setState()修改組件的狀態(tài)時,只需要傳入發(fā)生改變的state,而不是完整的state,因為組件state的更新是一個合并的過程:

this.state = {
?? ?title: 'React',
?? ?content: 'React is an wondeful JS library'
}

當(dāng)只需要修改title時,只需要將修改的title傳給setState即可:

this.setState({title:'ReactJs'});

react會合并最新的title到原來的狀態(tài),同時保留原來狀態(tài)的content,最終合并state為:

this.state = {
?? ?title: 'ReactJs',
?? ?content: 'React is an wondeful Js library'
}

state與不可變對象

react官方把state當(dāng)成不可變對象,一方面直接修改this.state,組件并不會重新render;另一方面,state中包含的所有狀態(tài)都應(yīng)該是不可變的對象,state當(dāng)中的某一個狀態(tài)發(fā)生變化時,應(yīng)該重新創(chuàng)建這個狀態(tài)對象,而不是直接修改原來的state狀態(tài),那么當(dāng)狀態(tài)發(fā)生變化時,如何去創(chuàng)建新的狀態(tài)呢,我們根據(jù)狀態(tài)類型可以分為下面三種情況:

狀態(tài)類型為不可變類型

number、string、boolean、null、undefined

這種情況最簡單,因為狀態(tài)是不可變類型,所以直接給要修改的狀態(tài)賦一個新值即可,例如我們要修改的count為number型,title(string),success(boolean)三個狀態(tài):

this.setState({
?? ?count:1,
?? ?title:'React',
?? ?success:true
})

狀態(tài)類型為數(shù)組

假如有一個數(shù)組類型的狀態(tài)books,當(dāng)向books中增加一本書時。

//方法一:使用preState,concat創(chuàng)建新數(shù)組
?this.setState((prevState)=>({
?? ?books: prevState.books.concat(['React Guide'])
}))
//方法二:ES6 spread syntax
this.setState(prevState=>({
?? ?books:[...prevState,'React Guide']
}))

當(dāng)我們從books中截取部分元素作為新狀態(tài)時,可以用數(shù)組的slice方法:

this.setState(prevState=>({
?? ?books: prevState.books.slice(1,3);
}))

當(dāng)從books中過濾部分元素后,作為新狀態(tài)時,可以使用filter方法:

this.setState(prevState=>({
?? ?books: prevState.books.filter(item=>{
?? ? ?return item!='React';
?? ?})
}))

【注意】不要使用push,pop,shift,unshift,splice等方法修改數(shù)組類型的狀態(tài),因為這些方法都是在原數(shù)組的基礎(chǔ)上修改的,而concat,slice,filter會返回一個新的數(shù)組。

狀態(tài)的類型是普通對象

(1) 使用es6的Object.assgin()方法

this.setState({
?? ?onwer: Object.assgin({},preState.onwer,{name:'Jason'});
})

(2) 使用對象擴(kuò)展語法(Object spread properties):

this.setState(preState=>{
?? ?owner: {...preState.owner, name:'Jason'}
})

總結(jié)

創(chuàng)建新的狀態(tài)的關(guān)鍵是避免使用直接修改原對象的方法,這種方法在vue中稱為變異方法,而是使用可以返回一個新對象的方法,當(dāng)然可以使用Immutable的JS庫(Immutable.js)實現(xiàn)類似的效果。

思考

為什么React推薦組件狀態(tài)的修改是不可變對象呢?

(1) 不可變對象的修改會返回一個新的對象,不用擔(dān)心原對象在不小心的情況下修改導(dǎo)致的錯誤,方便程序的管理和調(diào)試。

(2) 處于性能的考慮,對象組件的狀態(tài)是不可變對象時,在組件的shouldComponentUpdate方法中僅需要比較前后兩次狀態(tài)對象的引用就可以判斷狀態(tài)是否真的改變,從而避免不必要的render調(diào)用。

進(jìn)階

除了以上方法改變react組件的狀態(tài)之外,我們還經(jīng)常會用到replaceState()改變組件的狀態(tài)。

replaceState()方法與setState()類似,但是方法只會保留nextState中狀態(tài),原state不在nextState中的狀態(tài)都會被刪除。

//使用語法:
replaceState(object nextState[, function callback])
  • nextState,將要設(shè)置的新狀態(tài),該狀態(tài)會替換當(dāng)前的state。
  • callback,可選參數(shù),回調(diào)函數(shù)。該函數(shù)會在replaceState設(shè)置成功,且組件重新渲染后調(diào)用。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue.js中this如何取到data和method里的屬性詳解

    Vue.js中this如何取到data和method里的屬性詳解

    methods屬性是一個對象,通常我們會在這個對象中定義很多的方法,下面這篇文章主要給大家介紹了關(guān)于Vue.js中this如何取到data和method里的屬性,需要的朋友可以參考下
    2022-12-12
  • vue+elementui+vuex+sessionStorage實現(xiàn)歷史標(biāo)簽菜單的示例代碼

    vue+elementui+vuex+sessionStorage實現(xiàn)歷史標(biāo)簽菜單的示例代碼

    本文主要介紹了vue+elementui+vuex+sessionStorage實現(xiàn)歷史標(biāo)簽菜單的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Vue的緩存方法示例詳解

    Vue的緩存方法示例詳解

    這篇文章主要給大家介紹了關(guān)于Vue緩存方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • vue-router命名路由和編程式路由傳參講解

    vue-router命名路由和編程式路由傳參講解

    今天小編就為大家分享一篇關(guān)于vue-router命名路由和編程式路由傳參講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • vue中的模態(tài)對話框組件實現(xiàn)過程

    vue中的模態(tài)對話框組件實現(xiàn)過程

    這篇文章主要介紹了vue中的模態(tài)對話框組件實現(xiàn)過程,通過template定義組件,并添加相應(yīng)的對話框樣式,需要的朋友可以參考下
    2018-05-05
  • Vue axios設(shè)置訪問基礎(chǔ)路徑方法

    Vue axios設(shè)置訪問基礎(chǔ)路徑方法

    今天小編就為大家分享一篇Vue axios設(shè)置訪問基礎(chǔ)路徑方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    這篇文章主要介紹了vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-02-02
  • vue-admin-template解決登錄和跨域問題解決

    vue-admin-template解決登錄和跨域問題解決

    本文主要介紹了vue-admin-template解決登錄和跨域問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 淺談vue?腳手架文件結(jié)構(gòu)及加載過程

    淺談vue?腳手架文件結(jié)構(gòu)及加載過程

    這篇文章主要介紹了vue腳手架文件結(jié)構(gòu)及加載過程淺談,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • vue 使某個組件不被 keep-alive 緩存的方法

    vue 使某個組件不被 keep-alive 緩存的方法

    今天小編就為大家分享一篇vue 使某個組件不被 keep-alive 緩存的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09

最新評論

烟台市| 东至县| 枣阳市| 武强县| 甘南县| 通渭县| 宁海县| 专栏| 郎溪县| 龙南县| 贞丰县| 阿巴嘎旗| 沐川县| 红原县| 满城县| 沐川县| 浦北县| 金堂县| 平陆县| 肥东县| 海林市| 中西区| 上高县| 襄城县| 裕民县| 娱乐| 七台河市| 咸阳市| 谢通门县| 兴和县| 晴隆县| 五莲县| 周宁县| 莆田市| 铁岭县| 延吉市| 理塘县| 安平县| 蒲城县| 桐乡市| 略阳县|