I am working with react-redux
and I used routers turn pages to detail.js when I put the todo list.
It should have ownprops
properties on consoles, but mine was not defined.
Tell me where we’re wrong.
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;
I have no idea, personally I think I have followed below tutorial and router could not be same with them, the errors occurred.
2
Answers
You are using old React Redux code/patterns and
react-router-dom
doesn’t provide any props route props (e.g. there is nomatch
prop) to components. Use the React hooks from bothreact-redux
andreact-router-dom
to access theid
route path parameter and redux state selections.Example:
Detail
Home
Todo
Drew’s answer detailing how to use the updated pattern would be the preferred solution, but if for some reason this is not feasible and you are on at least React 16.8+ you can recreate a version of the
withRouter
HOC.This is detailed in the React Router FAQ, but for completeness the code snippet is as follows:
When using the
withRouter
HOC along side theconnect
HOC you will need to ensure they are used in the correct order to allow for the the Redux mapping functions to access the router properties.For example: