Javascript 如何更改connect方法中的部分代码(将使用mapStateToProps)以及此处出现的移动到index.js(action)的操作?

Javascript 如何更改connect方法中的部分代码(将使用mapStateToProps)以及此处出现的移动到index.js(action)的操作?,javascript,reactjs,redux,Javascript,Reactjs,Redux,我在Redux React上写了一个应用程序。您可以在沙盒中看到它是如何工作的: 我的应用程序工作正常,但我在app.js文件(主要组件)中对此代码的评论不好: 他们告诉我,我需要重新编写这个代码片段。因为只有MapStateTrops方法或mapDispatchToProps方法和组件本身需要传递(给予)到connect方法。 操作“运行过滤器”和“设置搜索”必须在index.js(操作)文件中 还告诉我,在index.js文件中: ReactDOM.render( <Provi

我在Redux React上写了一个应用程序。您可以在沙盒中看到它是如何工作的:

我的应用程序工作正常,但我在app.js文件(主要组件)中对此代码的评论不好:

他们告诉我,我需要重新编写这个代码片段。因为只有
MapStateTrops
方法或
mapDispatchToProps
方法和组件本身需要传递(给予)到connect方法。 操作“运行过滤器”和“设置搜索”必须在index.js(操作)文件中

还告诉我,在index.js文件中:


ReactDOM.render(
  <Provider store={store}>
    <ConnectedRoot />
  </Provider>,
  document.getElementById("root")
);

index.js:

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducers";
import thunk from "redux-thunk";
import { ConnectedRoot } from './containers/app';

const store = createStore(
  reducer, 
  {
    propReducer: {
      day: 1,
      data: [],
      filteredData: [],
      search: "",
      shift: "departure"
    }
  },
  applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRoot />
  </Provider>,
  document.getElementById("root")
);

从“React”导入React;
从“react dom”导入react dom;
从“react redux”导入{Provider};
从“redux”导入{createStore,applyMiddleware};
从“/reducers”导入减速机;
从“redux thunk”导入thunk;
从“./containers/app”导入{ConnectedRoot};
const store=createStore(
减速器,
{
减速器:{
日期:1,
数据:[],
过滤器数据:[],
搜索:“,
班次:“出发”
}
},
applyMiddleware(thunk)
);
ReactDOM.render(
,
document.getElementById(“根”)
);

为可能感兴趣的其他人更新了最终代码

我现在可能没有足够的时间完全回答你的问题,但我认为即使是部分回答也可能有所帮助。我会随着时间的推移更新这个

您的actions文件更准确地称为actions creator文件,并且不应该实际发送任何内容。通常,连接的组件将分派操作。考虑到这一点,更新后的actions.js如下:

// actions/index.js
export const loadDataStart = day => ({
  type: "LOAD_DATA_START",
  payload: day
});
export const loadDataEnd = (data, day) => ({
  type: "LOAD_DATA_END",
  payload: { data, day }
});
export const setShift = shift => ({
  type: "SET_SHIFT",
  payload: shift
});
export const runFilter = args => ({
  type: "RUN_FILTER",
  payload: { ...args }
});
export const setSearch = search => ({
  type: "SET_SEARCH",
  payload: search
});

我理解。我不能完全测试这个,但我希望它能为你指明正确的方向。你能对我的沙盒进行更改吗?因为您的代码需要与我的代码集成,才能使一切正常工作。我是redux的新手,这对我来说还很难。我的沙盒:通过按下按钮查看程序的工作方式,并尝试搜索filter@peterua当前位置我用叉子叉了它,在我走之前我会给你一些东西。同时,我把所有3个文件都放在了答案中。非常感谢你,我期待着你的帮助,因为我没有程序员朋友可以帮助我,我也没有同事在工作,因为我还在寻找我的第一份工作。这是我的沙箱。它还没有完全发挥作用,但我现在必须走了,我想这可能足以让你继续下去。
import React from "react";
import { Component } from "react";
import { connect } from "react-redux";
import { fetchData } from "../actions";
import TableData from "../components/TableData";
import TableSearch from "../components/TableSearch";
import Header from "../components/Header";
import Footer from "../components/Footer";
import "../components/app.css";

export function searchFilter(search, data) {
  return data.filter(n => n["planeTypeID.code"].toLowerCase().includes(search));
}

const days = ["12-11-2019", "13-11-2019", "14-11-2019"];

class Root extends React.Component {
  componentDidMount() {
    this.props.onFetchData(days[this.props.propReducer.day]);
  }

  render() {
    const { onFilter, onSetSearch, onFetchData } = this.props;
    const { search, shift, data, filteredData } = this.props.propReducer;

    return (
      <div>
        <div className="content">

        <Header/>
        <br/>
        <div className="searchTitle">SEARCH FLIGHT</div>
             <br/>
        <TableSearch value={search} onChange={e => onSetSearch(e.target.value)} 
         onSearch={value => onFilter({ search: value })}/>
             <br/>
             <br/>
        <div className="buttonShift">
          {data && Object.keys(data).map(n => (
            <button data-shift={n} onClick={e => onFilter({ shift: e.target.dataset.shift })} className={n === shift ? "active" : "noActive"}>
                {n}
            </button>
          ))}
        </div>

        <div className="row">
        <span className="title">Yesterday: </span><span className="title">Today: </span><span className="title">Tomorrow: </span>
        </div>

        <div className="buttonDays">
          {days && days.map((day, i) => (
            <button  key={day} onClick={() => onFetchData(day)} className="buttonDaysOne">
                {day} 
            </button>
          ))}
        </div>

        {data && <TableData data={filteredData} />}
          </div>
        <Footer/>
      </div>
    );
  }
}

export const ConnectedRoot = connect(
  state => state,
  dispatch => ({
    onFilter: args => dispatch({ type: "RUN_FILTER", ...args }),
    onSetSearch: search => dispatch({ type: "SET_SEARCH", search }),
    onFetchData: day => dispatch(fetchData(day))
  })
)(Root);

import { days } from "../containers/app";

export function fetchData(day) {
  return async dispatch => {
    dispatch({ type: "LOAD_DATA_START", day });
    const response = await fetch(`https://website.page.internal/someapi/first/${day}`);
    const data = (await response.json()).body;
    dispatch({ type: "LOAD_DATA_END", payload: { data, day } });
  };
}
export function setShift(shift) {
  return async dispatch => {
    dispatch({ type: "SET_SHIFT", shift });
  };
}

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducers";
import thunk from "redux-thunk";
import { ConnectedRoot } from './containers/app';

const store = createStore(
  reducer, 
  {
    propReducer: {
      day: 1,
      data: [],
      filteredData: [],
      search: "",
      shift: "departure"
    }
  },
  applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRoot />
  </Provider>,
  document.getElementById("root")
);

// actions/index.js
export const loadDataStart = day => ({
  type: "LOAD_DATA_START",
  payload: day
});
export const loadDataEnd = (data, day) => ({
  type: "LOAD_DATA_END",
  payload: { data, day }
});
export const setShift = shift => ({
  type: "SET_SHIFT",
  payload: shift
});
export const runFilter = args => ({
  type: "RUN_FILTER",
  payload: { ...args }
});
export const setSearch = search => ({
  type: "SET_SEARCH",
  payload: search
});
// containers/App.js
// This component should be changed to a functional component, especially in
// light of the componentWillUpdate warnings in the console.

// Since this project is already very different, I decided not to do that now
// to give you a better chance at understanding what I did.

import React, { Component } from "react";
import { connect } from "react-redux";

// NOTE: I consolidated the imports. see the ./components for more info
import { TableData, TableSearch } from "../components";

import * as actions from "../actions";

const days = ["12-11-2019", "13-11-2019", "14-11-2019"];

export function setShift(shift) {
  return async dispatch => {
    dispatch({ type: "SET_SHIFT", shift });
  };
}

class App extends Component {
  constructor(props) {
    super(props);
    this.fetchData = this.fetchData.bind(this);
  }

  // I extracted fetchData into a class function and bound it
  // in a new constructor, made only for this purpose.
  fetchData(day) {
    // I couldn't make an async class function, so I cheated
    // and embedded one here instead.
    const doFetchData = async () => {
      const { loadDataStart, loadDataEnd } = this.props;
      await loadDataStart(day);
      const response = await fetch(
        `https://api.iev.aero/api/flights/${days[day]}`
      );
      const data = (await response.json()).body;
      await loadDataEnd(data, day);
    };

    // call the embedded "cheat" function
    doFetchData();
  }
  componentDidMount() {
    this.fetchData(this.props.propReducer.day);
  }

  render() {
    const { onFilter, onSetSearch } = this.props;
    const { search, shift, data, filteredData } = this.props.propReducer;

    return (
      <div>
        <div className="content">
          <br />
          <div className="searchTitle">SEARCH FLIGHT</div>
          <br />
          <TableSearch
            value={search}
            onChange={e => onSetSearch(e.target.value)}
            onSearch={value => onFilter({ search: value })}
          />
          <br />
          <br />
          <div className="buttonShift">
            {data &&
              Object.keys(data).map((n, idx) => (
                <button
                  key={idx}
                  data-shift={n}
                  onClick={e => onFilter({ shift: e.target.dataset.shift })}
                  className={n === shift ? "active" : "noActive"}
                >
                  {n}
                </button>
              ))}
          </div>

          <div className="row">
            <span className="title">Yesterday: </span>
            <span className="title">Today: </span>
            <span className="title">Tomorrow: </span>
          </div>

          <div className="buttonDays">
            {days &&
              days.map((day, daysIndex) => (
                <button
                  key={day}
                  onClick={() => {
                    this.fetchData(daysIndex);
                  }}
                  className="buttonDaysOne"
                >
                  {day}
                </button>
              ))}
          </div>

          {data && <TableData data={filteredData} />}
        </div>
      </div>
    );
  }
}

export default connect(
  state => state,
  {
    // Note that fetchData is no longer an action
    onFilter: actions.runFilter,
    onSetSearch: actions.setSearch,
    loadDataStart: actions.loadDataStart,
    loadDataEnd: actions.loadDataEnd
  }
)(App);
// index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducers";
import thunk from "redux-thunk";
import App from "./containers/App";

const initialState = {
  propReducer: {
    day: 1,
    data: [],
    filteredData: [],
    search: "",
    shift: "departure"
  }
};

const store = createStore(reducer, initialState, applyMiddleware(thunk));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
// utils.js
export function searchFilter(search, data) {
  return data.filter(n => n["planeTypeID.code"].toLowerCase().includes(search));
}
// reducers/airplanes.js
import { searchFilter } from "../utils";

const actions = {
  SET_SHIFT: (state, action) => ({
    ...state,
    shift: action.payload.shift
  }),
  SET_SEARCH: (state, action) => {
    return {
      ...state,
      search: action.payload.toLowerCase()
    };
  },
  RUN_FILTER: (state, action) => {
    const { shift = state.shift, search = state.search } = action.payload;
    const newData = state.data[shift].filter(x =>
      x["planeTypeID.code"].toLowerCase().includes(search)
    );

    const filteredData = searchFilter(state.search, newData);
    return {
      ...state,
      search,
      filteredData,
      shift
    };
  },
  LOAD_DATA_START: (state, action) => ({ ...state, day: action.payload.day }),
  LOAD_DATA_END: (state, action) => {
    const { data, search: actionSearch } = action.payload;
    const { shift, search: stateSearch } = state;
    const newData = data[shift].filter(x => {
      try {
        const needle = x["planeTypeID.code"].toLowerCase();
        return needle.includes(actionSearch || stateSearch);
      } catch (err) {
        // TypeError: Cannot read property 'toLowerCase' of undefined
        // this means that the code doesn't exist
        return false;
      }
    });
    const filteredData = searchFilter(state.search, newData);
    return {
      ...state,
      data,
      shift: Object.keys(data)[0],
      filteredData
    };
  }
};

export function reducer(state = {}, action) {
  if (action.type in actions) {
    return actions[action.type](state, action);
  }
  return state;
}