vue和react中props變化後修改state的方式 vue vue react 改進

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

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,比如隨機默認值案例

vue

Vue提供了一種更通用的方式來觀察和響應Vue實例上的數據變動:偵聽屬性 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 會在調用 render 方法之前調用,並且在初始掛載及後續更新時都會被調用。它應返回一個對象來更新 state,如果返回 null 則不更新任何內容。

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

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} />
      </>
    );
  }
}

改進

直接複製 propstate 是一個非常糟糕的想法。這兩者的關鍵在於,任何數據,都要保證只有一個數據來源,而且避免直接複製它。

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">默認值</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}>默認值</button>
        </div>
      </>
    );
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章