React Redux通过从API获取数据来设置初始状态

时间:2019-08-25 07:25:24

标签: reactjs redux axios

我编写了一个react redux应用,一切正常,现在我正在尝试实现我的初始数据应该来自API端点,

这是我的postReducers.py文件:

var initialState = {
  employees: []
};

var postReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_POST':
      return {
        ...state,
        employees: [...state.employees, action.data],
      };
    case 'EDIT_POST':
      return {
        ...state,
        employees: state.employees.map(emp => emp.id === action.data.id ? action.data : emp)
      };
      case 'DELETE_POST':
        console.log(action.data.id)
        return {
           ...state,
           employees: [...state.employees.filter((post)=>post.id !== action.data.id)],
        };
    default:
      return state;
  }
};


export default postReducer;

这是我的table.js文件

import React, {Fragment} from "react";
import { connect } from "react-redux";
const axios = require('axios');

class Table extends React.Component {
    onEdit = (item) => {  //Use arrow function to bind `this`
        this.props.selectedData(item);
    }

    onDelete = (id) => {
        const data = {
            id,
        }
        this.props.dispatch({ type: 'DELETE_POST', data });
    }

    render() {
        return (
            <Fragment>
                <thead>
                    <tr>
                        <th scope="col">Name</th>
                        <th scope="col">Age</th>
                        <th scope="col">Edit</th>
                        <th>Delete</th>
                    </tr>
                </thead>
                <tbody>
                {this.props.employees.map((item, index) => (
                    <tr key={index}>
                        <td>{item.name}</td>
                        <td>{item.age}</td>
                        <td>
                            <button
                                type="button"
                                onClick={() => this.onEdit(item)}>EDIT
                            </button>
                            <button
                                onClick={ () => this.onDelete(item.id) }>DELETE
                            </button>
                        </td>
                    </tr>
                ))}
                </tbody>
            </Fragment>
        );
    }
}

const mapStateToProps = (state) => ({ employees: state.employees });

export default connect(mapStateToProps)(Table);

这是我的App.js文件

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Home from '../components/home'
import Contacts from '../components/contact'
import About from '../components/about'

class App extends Component {
  render() {
    return (
    <Router>
      <p>A simple webpack for django and react</p>
        <div>
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
          <ul className="navbar-nav mr-auto">
            <li><Link to={'/'} className="nav-link"> Home </Link></li>
            <li><Link to={'/contact'} className="nav-link">Contact</Link></li>
            <li><Link to={'/about'} className="nav-link">About</Link></li>
          </ul>
          </nav>
          <hr />
          <Switch>
              <Route exact path='/' component={Home} />
              <Route path='/contact' component={Contacts} />
              <Route path='/about' component={About} />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

这是我的home.js文件

import React from "react"
import Table from "../components/table"
import Form from '../components/form'

class Home extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
           selectedData: {name: '', age: ''},
           isEdit: false
        };
    }

    selectedData = (item) => {
       this.setState({selectedData: item,isEdit:true})
    }
    render() {
        return (
            <React.Fragment>   
              <Form selectedData={this.state.selectedData} isEdit={this.state.isEdit}/>          
            <table>
                <Table selectedData={this.selectedData} />
            </table>
            </React.Fragment>
        );
    }
}
export default Home;

这是我的Form.js文件:

import React, { Fragment } from "react"
import { connect } from 'react-redux'
const axios = require('axios');

class Form extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      id: this.props.selectedData.id, 
      name: this.props.selectedData.name, 
      age: this.props.selectedData.age,
    };
    this.onHandleChange = this.onHandleChange.bind(this);
    this.submit = this.submit.bind(this);
  }


  submit(event) {
    const data = {
      name: this.state.name, 
      age: this.state.age, 
      email: this.state.email
    };
    if (this.props.isEdit) {
      data.id = this.props.selectedData.id;
      console.log('edit', data);
      this.props.dispatch({ type: 'EDIT_POST', data })
    } else {
      // generate id here for new emplyoee
      this.props.dispatch({ type: 'ADD_POST', data })
    }
  }

  onHandleChange(event) {
    this.setState({
      [event.target.name]: event.target.value
    });
  }

  componentDidUpdate(prevProps) {
    if (prevProps.selectedData.age !== this.props.selectedData.age) {  //Check on email, because email is unique
      this.setState({ name: this.props.selectedData.name, age: this.props.selectedData.age })
    }
  }



  render() {
    return (
      <form>
        <div className="form-group">
          <input onChange={(event) => this.onHandleChange(event)} value={this.state.name} name="name" type="text" />
        </div>

        <div className="form-group">
          <input onChange={(event) => this.onHandleChange(event)} value={this.state.age} name="age" type="number" />
        </div>

        <button onClick={(event) => this.submit(event)} type="button">
          {this.props.isEdit ? 'Update' : 'SAVE'}
        </button>

      </form>
    );
  }
}

export default connect(null)(Form);

这是我的index.js文件:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom'

import App from "../client/components/App";

import { Provider } from 'react-redux'

import { createStore } from 'redux'
import postReducer from '../client/postReducer'

const store = createStore(postReducer)


// if we don't subcribe, yet our crud operation will work
function onStateChange() {
  const state = store.getState();
}

store.subscribe(onStateChange)

ReactDOM.render((
  <BrowserRouter>
      <Provider store={store}>
        <App />
      </Provider>
  </BrowserRouter>
), document.getElementById('app'))

任何人都可以帮助我实现我的initialState,以便在我访问页面或加载表时,表应该从API端点获取数据吗?

我的API端点是:http://127.0.0.1:8000/employees/,它只有两个字段nameage

我正在将axios用于http请求

我在stackoverflow上进行了搜索,一个人显示了一个可能重复的帖子,但这并不能解决我的问题,因为它是本机反应

1 个答案:

答案 0 :(得分:0)

您可以在使用表组件的home.js中获取数据。您可以使用componentDidMount()之类的操作来获取SET_EMPLOYEES_LIST中的数据并将数据传递给您的reducer:

home.js:

import React from "react"
import Table from "../components/table"
import Form from '../components/form'
import { setEmployeesList } from './actions'
class Home extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
           selectedData: {name: '', age: ''},
           isEdit: false
        };
    }

    componentDidMount(){
       Axios.get(URL).then(res => this.props.setEmployeesList(res.data))
    }

    selectedData = (item) => {
       this.setState({selectedData: item,isEdit:true})
    }
    render() {
        return (
            <React.Fragment>   
              <Form selectedData={this.state.selectedData} isEdit={this.state.isEdit}/>          
            <table>
                <Table selectedData={this.selectedData} />
            </table>
            </React.Fragment>
        );
    }
}
const mapDispatchToProps = dispatch => {
   return {
      setEmployeesList: data => dispatch(setEmployeesList(data)) // Set the action you created in your component props
   }
}
export default Home;

action.js:

import {SET_EMPLOYEES_LIST} from './constants'
export const setEmployeesList = payload => ({ type: SET_EMPLOYEES_LIST, payload })

constants.js:

export const SET_EMPLOYEES_LIST = 'SET_EMPLOYEES_LIST'

postReducers.js:

import {SET_EMPLOYEES_LIST} from './constants'
const initialState = {
  employees: []
};

const postReducer = (state = initialState, action) => {
  switch (action.type) {
    case SET_EMPLOYEES_LIST:
      return {
        ...state,
        employees: action.payload,
      };
    case 'ADD_POST':
      return {
        ...state,
        employees: [...state.employees, action.data],
      };
    case 'EDIT_POST':
      return {
        ...state,
        employees: state.employees.map(emp => emp.id === action.data.id ? action.data : emp)
      };
      case 'DELETE_POST':
        console.log(action.data.id)
        return {
           ...state,
           employees: [...state.employees.filter((post)=>post.id !== action.data.id)],
        };
    default:
      return state;
  }
};


export default postReducer;