我见过类似的问题,但它们似乎无济于事。我有一个要在其上实现redux的React项目。
我的index.js如下:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "./store/reducer";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
const store = createStore(reducer);
const app = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
ReactDOM.render(app, document.getElementById("root"));
serviceWorker.unregister();
我的reducer.js就像这样:
import * as actionTypes from "./actions";
const initialState = {
searchValue: "",
finalSearchValue: ""
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.UPDATE_INPUT_VALUE:
return {
searchValue: state.searchValue
};
case actionTypes.SUBMIT_QUERY:
return {
finalSearchValue: state.finalSearchValue
};
default:
return state;
}
};
export default reducer;
还有我的Songfinder.js-我要在其中映射mapStateToProps和mapDispatchToProps的地方是这样的:
import React, { Component } from "react";
import { connect } from "react-redux";
import PanelSearchResults from "../../components/PanelSearchResults/PanelSearchResults";
import Playlist from "../Playlist/Playlist";
import classes from "./SongFinder.css";
import Auxilliary from "../../hoc/Auxilliary";
import * as actionTypes from "../../store/actions";
class SongFinder extends Component {
props: {
searchValue: string;
finalSearchValue: string;
};
componentDidMount() {
console.log(this.props);
}
updateInputValue(evt) {
this.props.onUpdateSearchValue(evt.target.value);
}
onSubmitQueryHandler() {}
render() {
if (this.props) {
return (
<Auxilliary>
<div className={classes.panel}>
<input
className="searchBox"
type="text"
value={this.props.searchValue}
onChange={evt => this.updateInputValue(evt)}
/>
<button type="submit" onClick={this.onSubmitQueryHandler}>
Submit
</button>
</div>
<div className={classes.panel}>
<h1>Playlist</h1>
<Playlist />
</div>
<PanelSearchResults search={this.props.finalSearchValue} />
</Auxilliary>
);
} else {
return null;
}
}
}
const mapStateToProps = state => {
return {
searchValue: state.searchValue,
finalSearchValue: state.finalSearchValue
};
};
const mapDispatchToProps = dispatch => {
return {
onUpdateSearchValue: value =>
dispatch({
type: actionTypes.UPDATE_INPUT_VALUE,
searchValue: value
}),
onSubmitQuery: value =>
dispatch({
type: actionTypes.SUBMIT_QUERY,
finalSearchValue: value
})
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(SongFinder);
每次更改输入文本时,我都希望通过mapDispatchToProps更新状态,并且希望onChange事件触发updateInputValue处理程序,该处理程序应触发mapDispatchToProps中的onUpdateSearchValue,并将其发送给evt.target.value。
将头发撕裂,试图弄清楚为什么它不起作用。我在React 16.6.3中-是Typescript错误吗?在reducer中声明的我的initialState中的两个值都通过Songfinder.js中的componentDidMount()登录到控制台,因此该组件可以使用道具吗?
答案 0 :(得分:1)
看起来像您的问题是reducer实际上并没有创建任何新状态,因为在派生新状态时您是指state
而不是action
。 state
参数包含reducer上次运行以来的先前状态,而action
包含您这次需要导出新状态的信息。像这样:
import * as actionTypes from "./actions";
const initialState = {
searchValue: "",
finalSearchValue: ""
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.UPDATE_INPUT_VALUE:
return {
searchValue: action.searchValue,
finalSearchValue: ""
};
case actionTypes.SUBMIT_QUERY:
return {
searchValue: "",
finalSearchValue: action.finalSearchValue
};
default:
return state;
}
};
export default reducer;
我还在上面的返回值中添加了额外的字段,因为化简器可能每次应该返回一个完整的状态(与initialState
相同的形状)。