1. 程式人生 > >React封裝Fetch獲取Api, 父元件與子元件的通訊

React封裝Fetch獲取Api, 父元件與子元件的通訊

一個專案下來,和後臺資料的互動實在是太多了,如果不封裝一下就感覺怪怪的,而且也很不DRY.封裝起來之後,會省事很多很多.

封裝Fetch

// MyFetch.js
const API_URL = process.env.REACT_APP_DEV_API_URL
var methods = {
    get(path) {
      return new Promise((resolve, reject) => {
          fetch(`${API_URL}/${path}`,{
              headers: new Headers({
                  'my-token'
: "xxxxx...", 'Accept': 'application/json', 'Content-Type': 'application/json', }) }).then(res => { if (res.ok) { return res.json(); } else if(res.status === 500) { let errors = `${res.status}, ${res.statusText}
` throw errors } else if (res.status === 404) { let errors = `${res.status}, ${res.statusText}` throw errors }else if (res.status === xxx) { } }) .then(json => { resolve(json); }) .catch
(err => { reject(err); }); })
; }, } export default methods

呼叫的時候也很簡單.

import MyFetch from './MyFetch';
MyFetch.get(users).then(data => {
  console.log("respond data is", data)
})

這樣就可以在Get請求的時候統一呼叫該介面,進行了一次封裝.

父子元件的通訊

  • 父元件傳遞資料到子元件.
import React, {Component} from 'react';

export default class Parent extends Component{
    render() {
        return(
            <Child name={'issue'} age='1'/>
        )
    }
}

export default class Child extends Component {
    constructor(props){
        super(props);
        console.log(this.props.name, this.props.age)
        //會獲得對應的資料.('issue', '1')
    }
}
  • 子元件傳遞資料到父元件
import React, {Component} from 'react';

export default class Parent extends Component{
    render() {
        return(
            <Child name={this.name} />
        )
    }

    name = (value) => {
        console.log("receive name value is", value)
    }
}

export default class Child extends Component {
    render(){
        return(
            <input onChange={this.handleChange} />
        )
    }

    handleChange = (e) => {
        let value = e.target.value
        this.props.name(value)
    }
}

這樣就可以把獲取到的使用者輸入的內容傳遞給父元件了.

需要注意: 父元件載入子元件,子元件的建構函式只會執行一次.

如果父元件(容器元件)獲取遠端資料,傳遞到子元件,不要在子元件的狀態裡寫入資料.直接使用props.data去獲取.
舉例如下:

import React, {Component} from 'react';

export default class Parent extends Component{
    state = {
        users: []
    }

    componentDidMount() {
        MyFetch.get('users').then(data => {
            this.setState({
                users: data.users
            })
        })
    }

    render() {
        return(
            <Child dataSource={this.state.users} />
        )
    }
}

export default class Child extends Component {
    constructor(props){
        super(props);
        this.state = {
            users: this.props.users
        }
    }
    render(){
        console.log(this.state.users) #[]
        console.log(this.props.users) #[{user1},{user2},...]
        return(
            <table>
                xxx
            </table>
        )
    }
}

出現上面這種情況是因為父元件在獲取到資料之前就已經載入了子元件.但是子元件在一個生命週期,建構函式只會執行一次.所以父元件改變狀態之後,是無法再次執行子元件建構函式的內容.