Reactjs Redux can';t处理来自2个输入的数据

Reactjs Redux can';t处理来自2个输入的数据,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我试图用一个函数控制我的组件的状态数据。我也在使用redux。但是redux有些问题,或者我看不出我的错误。这是我的组成部分: this.state = { data: this.props.ui.users, name: '', email: '' } } handleChange = (evt) => { this.setState({ [evt.target.name]: e

我试图用一个函数控制我的组件的状态数据。我也在使用redux。但是redux有些问题,或者我看不出我的错误。这是我的组成部分:

      this.state = {
         data: this.props.ui.users,
         name: '',
         email: ''
      }
    }


    handleChange = (evt) => {
      this.setState({ [evt.target.name]: evt.target.value });
    }


    componentWillReceiveProps = () => {
      this.setState({
        name: ''
      })
    }


    render() {
      return (
        <div>
          <form onSubmit={(e) => this.props.uiActions.addUser(e, this.state.name, this.state.email)}>
            <input type="text"
                   name="name"
                   value={this.state.name}
                   onChange={this.handleChange}/>
          </form>
      </div>
      )
    }
}
减速器:

export default (state = initialState, action) => {
  switch (action.type) {
  case UI_ACTIONS.SET_REPOS: 
    return { ...state, users: action.users };
  case UI_ACTIONS.ADD_USER:
    return {...state, users: action.users};
  default:
    return state;
  }
};

我做错了什么?在这里您可以找到我的repo:

我看到一件我觉得不对的事情是:input元素没有绑定到
this

<input type="text" name="name" value={this.state.name} 
  onChange={this.handleChange.bind(this)}
/>


您还跟踪了您的事件处理程序在控制台中执行的操作吗?

我发现有一件事似乎不对:输入元素未绑定到
this

<input type="text" name="name" value={this.state.name} 
  onChange={this.handleChange.bind(this)}
/>


您还跟踪了您的事件处理程序在控制台中执行的操作吗?

这里有很多事情需要修改。你构建应用程序的方式是反模式的(非标准/糟糕的做法),随着应用程序变得更加动态,这会给你带来更多麻烦

需要考虑的几件事:

  • 您不需要Redux,除非您使用的是大量嵌套的组件(在本例中,React状态就足够了)
  • 您应该将容器(Redux连接的函数/AJAX请求)与组件(关心事物外观的任何函数)分开:
  • form
    操作保留在表单组件中(如
    e.preventDefault();
    ),并从
    减速机中使用Redux状态(您可以访问减速机中的Redux状态,因此对于
    addUser
    操作,无需调用Redux的
    getState();
  • 如果只返回
    类型
    有效载荷
    ,则不需要
    分派
    操作
  • 总是
    .catch()
    你的承诺。
    出于某种原因,现在有一种趋势,新兴的开发人员认为每一个承诺都会解决,而且永远不会出错。未捕获错误将中断您的应用程序
我已经着手重组了整个应用程序。我鼓励您解构它并遵循应用程序流程,然后执行您的项目并相应地进行修复

工作示例:

操作/index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
组件/App.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
root/index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
从“React”导入React;
从“react dom”导入{render};
从“/root”导入应用程序;
导入“uikit/dist/css/uikit.min.css”;
render(,document.getElementById(“根”));

这里有很多事情需要修改。你构建应用程序的方式是反模式的(非标准/糟糕的做法),随着应用程序变得更加动态,这会给你带来更多麻烦

需要考虑的几件事:

  • 您不需要Redux,除非您使用的是大量嵌套的组件(在本例中,React状态就足够了)
  • 您应该将容器(Redux连接的函数/AJAX请求)与组件(关心事物外观的任何函数)分开:
  • form
    操作保留在表单组件中(如
    e.preventDefault();
    ),并从
    减速机中使用Redux状态(您可以访问减速机中的Redux状态,因此对于
    addUser
    操作,无需调用Redux的
    getState();
  • 如果只返回
    类型
    有效载荷
    ,则不需要
    分派
    操作
  • 总是
    .catch()
    你的承诺。
    出于某种原因,现在有一种趋势,新兴的开发人员认为每一个承诺都会解决,而且永远不会出错。未捕获错误将中断您的应用程序
我已经着手重组了整个应用程序。我鼓励您解构它并遵循应用程序流程,然后执行您的项目并相应地进行修复

工作示例:

操作/index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
组件/App.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
root/index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
index.js

import { UI_ACTIONS } from "../types";

export const fetchUsers = () => dispatch => {
  fetch(`https://jsonplaceholder.typicode.com/users`)
    .then(resp => resp.json())
    .then(data => dispatch({ type: UI_ACTIONS.SET_REPOS, payload: data }))
    .catch(err => console.error(err.toString()));
};

/* 
  export const handleNameChange = value => ({
    type: UI_ACTIONS.UPDATE_NAME, 
    val: value
  })
*/

/*
  export const handleEmailChange = value => ({
    type: UI_ACTIONS.UPDATE_EMAIL, 
    val: value
  }) 
*/

export const addUser = (name, email) => ({
  type: UI_ACTIONS.ADD_USER,
  payload: { name: name, email: email }
});
import React from "react";
import UserListForm from "../containers/UserListForm";

export default ({ children }) => <div className="wrapper">{children}</div>;
import map from "lodash/map";
import React from "react";

export default ({ users }) => (
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>USER</th>
        <th>E-MAIL</th>
      </tr>
    </thead>
    <tbody>
      {map(users, ({ id, name, email }) => (
        <tr key={email}>
          <td>{id}</td>
          <td>{name}</td>
          <td>{email}</td>
        </tr>
      ))}
    </tbody>
    <tfoot />
  </table>
);
import map from "lodash/map";
import React, { Component } from "react";
import { connect } from "react-redux";
import { addUser, fetchUsers } from "../actions/uiActions";
import DisplayUserList from "../components/displayUserList";

class Userlist extends Component {
  state = {
    name: "",
    email: ""
  };

  componentDidMount = () => {
    this.props.fetchUsers();
  };

  handleChange = evt => {
    this.setState({ [evt.target.name]: evt.target.value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { email, name } = this.state;

    if (!email || !name) return;

    this.props.addUser(name, email);
    this.setState({ email: "", name: "" });
  };

  render = () => (
    <div style={{ padding: 20 }}>
      <h1 style={{ textAlign: "center" }}>Utilizing Redux For Lists</h1>
      <form style={{ marginBottom: 20 }} onSubmit={this.handleSubmit}>
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="name"
          placeholder="Add user's name..."
          value={this.state.name}
          onChange={this.handleChange}
        />
        <br />
        <input
          className="uk-input"
          style={{ width: 300, marginBottom: 10 }}
          type="text"
          name="email"
          placeholder="Add user's email..."
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button className="uk-button uk-button-primary" type="submit">
          Submit
        </button>
      </form>
      <DisplayUserList users={this.props.users} />
    </div>
  );
}

export default connect(
  state => ({ users: state.ui.users }),
  { addUser, fetchUsers }
)(Userlist);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { UI_ACTIONS } from "../types";

const initialState = {
  users: [],
  name: "",
  email: ""
};

const uiReducer = (state = initialState, { payload, type }) => {
  switch (type) {
    case UI_ACTIONS.SET_REPOS:
      return { ...state, users: payload };
    case UI_ACTIONS.ADD_USER:
      return {
        ...state,
        users: [...state.users, { id: state.users.length + 1, ...payload }]
      };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  ui: uiReducer,
  routing
});

export default rootReducer;
import React from "react";
import { browserHistory, Router } from "react-router";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import routes from "../routes";

// CONFIG REDUX STORE WITH REDUCERS, MIDDLEWARES, AND BROWSERHISTORY
const store = createStore(rootReducer, applyMiddleware(thunk));
const history = syncHistoryWithStore(browserHistory, store);

// APP CONFIG'D WITH REDUX STORE, BROWSERHISTORY AND ROUTES
export default () => (
  <Provider store={store}>
    <Router
      onUpdate={() => window.scrollTo(0, 0)}
      history={history}
      routes={routes}
    />
  </Provider>
);
import React from "react";
import { IndexRoute, Route } from "react-router";

import App from "../components/App";
import UserListForm from "../containers/UserListForm";

export default (
  <Route path="/" component={App}>
    <IndexRoute component={UserListForm} />
  </Route>
);
export const UI_ACTIONS = {
  UPDATE_NAME: "UPDATE_NAME",
  INCREMENT_COUNT: "INCREMENT_COUNT",
  SET_REPOS: "SET_REPOS",
  ADD_USER: "ADD_USER",
  UPDATE_NAME: "UPDATE_NAME",
  UPDATE_EMAIL: "UPDATE_EMAIL"
};

export const TEST_ACTION = {
  ACTION_1: "ACTION_1"
};
import React from "react";
import { render } from "react-dom";
import App from "./root";
import "uikit/dist/css/uikit.min.css";

render(<App />, document.getElementById("root"));
从“React”导入React;
从“react dom”导入{render};
从“/root”导入应用程序;
导入“uikit/dist/css/uikit.min.css”;
render(,document.getElementById(“根”));

他不需要绑定函数,因为它是一个箭头函数。另外,不建议您在render中直接绑定。他不需要绑定函数,因为它是一个箭头函数。另外,不建议您直接在render中绑定。无法理解什么不适合您。你能不能解释一下,什么东西不适合你。请你说得具体点好吗?谢谢。这是你投入的大量工作。在大多数情况下,我的代码质量很差(无法捕捉错误),这是因为我只想让它与redux一起工作(我在学习它时遇到问题)。尽管如此,我还是会在一天内尝试你的代码,因为据我所知,我必须安装更多的软件包,比如lodash。再次感谢您。您不必安装
lodash
。这更多的是个人对普通函数的偏好,比如
映射
每个
过滤器
…等等。我正在查看您编写的代码,我有一个问题。为什么在那个示例中我们需要react路由器?如果您计划拥有多条路由,只需添加一个
,就可以利用
react路由器
,现在
/
/example
是两个不同的视图。。。否则,你就不需要了。谢谢。这是你投入的大量工作。在大多数情况下,我的代码质量很差(无法捕捉错误),这是因为我只想让它与redux一起工作(我在学习它时遇到问题)。尽管如此,我还是会在一天内尝试你的代码,因为据我所知,我必须安装更多的软件包,比如lodash。再次感谢您。您不必安装
lodash
。它更像是个人对普通函数的偏好,比如
map
each
filter
…等等。