React Redux不更新onChange上的文本输入

时间:2019-09-30 20:54:50

标签: reactjs typescript redux react-redux

我见过类似的问题,但它们似乎无济于事。我有一个要在其上实现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()登录到控制台,因此该组件可以使用道具吗?

1 个答案:

答案 0 :(得分:1)

看起来像您的问题是reducer实际上并没有创建任何新状态,因为在派生新状态时您是指state而不是actionstate参数包含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相同的形状)。