Javascript 如何更改connect方法中的部分代码(将使用mapStateToProps)以及此处出现的移动到index.js(action)的操作?
我在Redux React上写了一个应用程序。您可以在沙盒中看到它是如何工作的: 我的应用程序工作正常,但我在app.js文件(主要组件)中对此代码的评论不好: 他们告诉我,我需要重新编写这个代码片段。因为只有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
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;
}