React-redux ownprops是空的,所以我不能得到匹配和参数

z9smfwbn  于 2023-03-18  发布在  React
关注(0)|答案(2)|浏览(148)

我正在使用react-redux,当我放todo列表时,我使用路由器翻页到detailiderjs。
它应该在控制台上有ownprops属性,但我的属性没有定义。
告诉我我们哪里错了。
App.js

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Detail from "../routes/Detail";
import Home from "../routes/Home";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/:id" element={<Detail />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Todos.js

import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { actionCreators } from '../store';

function Todo({ text, onBtnClick, id }) {
  return (
    <li>
      <Link to={`/${id}`}>{text}</Link>
      <button onClick={onBtnClick}>delete</button>
    </li>
  );
}

function mapDispatchToProps(dispatch, ownProps) {
  console.log(ownProps);
  return {
    onBtnClick: () => dispatch(actionCreators.deleteToDo(ownProps.id)),
  };
}

export default connect(null, mapDispatchToProps)(Todo); // 삭제는 state를 상관할 필요 x

Details.js

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

function Detail({ toDo }) {
  return (
    <>
      <h1>{toDo?.text}</h1>
      <h5>Created at: {toDo?.id}</h5>
    </>
  );
}

function mapStateToProps(state, ownProps) {
  console.log("ownProps: ", ownProps);
  const {
    match: {
      params: { id },
    },
  } = ownProps.match.params;
  console.log("id: ", id);
  return { toDos: state.find((toDo) => toDo.id === parseInt(id)) };
}

export default connect(mapStateToProps)(Detail);

Home.js

import React, { useState } from "react";
import { connect } from "react-redux";
import Todo from "../components/ToDo";
import { actionCreators } from "../store";

function Home({ toDos, addTodo }) {
  // we are creating props

  const [text, setText] = useState("");
  function onChange(e) {
    setText(e.target.value);
  }

  function onSubmit(e) {
    e.preventDefault();
    addTodo(text);
    console.log(text);
    setText("");
  }

  return (
    <>
      <h1>To Do</h1>
      <form onSubmit={onSubmit}>
        <input type="text" value={text} onChange={onChange} />
        <button>Add</button>
        <ul>
          {toDos.map((toDo) => (
            <Todo {...toDo} key={toDo.id} />
          ))}
        </ul>
      </form>
    </>
  );
}

function mapStateToProps(state) {
  return { toDos: state };
}

function mapDispatchToProps(dispatch) {
  return { addTodo: (text) => dispatch(actionCreators.addToDo(text)) };
}

export default connect(mapStateToProps, mapDispatchToProps)(Home);

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";

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

store.js

import { createStore } from "redux";

const ADD = "ADD";
const DELETE = "DELETE";

const addToDo = (text) => {
  return {
    type: ADD,
    text,
  };
};

const deleteToDo = (id) => {
  return {
    type: DELETE,
    id: parseInt(id),
  };
};

const reducer = (state = [], action) => {
  switch (action.type) {
    case ADD:
      return [{ text: action.text, id: Date.now() }, ...state];
    case DELETE:
      return state.filter((toDo) => toDo.id !== action.id);
    default:
      return state;
  }
};

const store = createStore(reducer);

// store.subscribe(); 변화가 있으면 re-render하기 바람.

export const actionCreators = {
  addToDo,
  deleteToDo,
};

export default store;

我不知道,我个人认为我已经按照下面的教程和路由器不可能与他们相同,错误发生。
https://nomadcoders.co/redux-for-beginners/lectures/1620

kyxcudwk

kyxcudwk1#

您正在使用旧的React Redux代码/模式,并且react-router-dom未向组件提供任何props路由props(* 例如,没有match prop*)。请使用react-reduxreact-router-dom的React挂接访问id路由路径参数和redux状态选择。
示例:
细节

<Route path="/:id" element={<Detail />} /> // no additional props passed
import React from "react";
import { useSelector } from "react-redux";
import { useParams } from 'react-router-dom';

function Detail() {
  const { id } = useParams();
  const todo = useSelector(state => state.find(todo => String(todo.id) === id));

  return (
    <>
      <h1>{todo?.text}</h1>
      <h5>Created at: {todo?.id}</h5>
    </>
  );
}

export default Detail;

import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Todo from "../components/ToDo";
import { actionCreators } from '../store';

function Home() {
  const dispatch = useDispatch();

  const todos = useSelector(state => state);

  // we are creating props

  const [text, setText] = useState("");
  function onChange(e) {
    setText(e.target.value);
  }

  function onSubmit(e) {
    e.preventDefault();
    dispatch(actionCreators.addTodo(text));
    setText("");
  }

  return (
    <>
      <h1>To Do</h1>
      <form onSubmit={onSubmit}>
        <input type="text" value={text} onChange={onChange} />
        <button>Add</button>
        <ul>
          {todos.map((todo) => (
            <Todo {...todo} key={todo.id} />
          ))}
        </ul>
      </form>
    </>
  );
}

export default Home;

托多

import React from 'react';
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import { actionCreators } from '../store';

function Todo({ text, id }) {
  const dispatch = useDispatch();

  const onBtnClick = () => {
    dispatch(actionCreators.deleteTodo(id));
  };

  return (
    <li>
      <Link to={`/${id}`}>{text}</Link>
      <button onClick={onBtnClick}>delete</button>
    </li>
  );
}

export default Todo;

ttvkxqim

ttvkxqim2#

Drew's answer详细说明如何使用更新的模式将是首选解决方案,但如果由于某种原因这不可行,并且您至少使用React 16.8+,则可以重新创建withRouter HOC的版本。
React Router常见问题解答中对此进行了详细说明,但为了完整起见,代码片段如下所示:

import {
  useLocation,
  useNavigate,
  useParams,
} from "react-router-dom";

function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    let location = useLocation();
    let navigate = useNavigate();
    let params = useParams();
    return (
      <Component
        {...props}
        router={{ location, navigate, params }}
      />
    );
  }

  return ComponentWithRouterProp;
}

在使用withRouter HOC沿着connect HOC时,您需要确保它们的使用顺序正确,以便ReduxMap功能访问路由器属性。
例如:

function mapStateToProps(state, ownProps) {
  console.log("ownProps: ", ownProps);
  const { id } = ownProps.router.params;
  console.log("id: ", id);
  return { toDos: state.find((toDo) => toDo.id === parseInt(id)) };
}

export default withRouter(connect(mapStateToProps)(Detail));

相关问题