props.history.push не работает должным образом и перенаправляет на тот же маршрут

#reactjs #react-redux #react-router #react-router-dom #react-props

#reactjs #реагировать-redux #react-маршрутизатор #react-router-dom #react-props

Вопрос:

Итак, я создаю базовое приложение React с 3 компонентами: CreateRoom, SetUsername и Window. Сначала я перехожу к компоненту CreateRoom с помощью простого <Link to="/createRoom" >create a room</Link> , затем в компоненте CreateRoom, после того как пользователь установил название комнаты, я перехожу к компоненту SetUsername через props.history.push({pathname}) и передаю Room_name через props.history.push() , затем, как только я нахожусь в компоненте SetUsername, я жду, пока пользователь установит имя пользователя, и снова передаю это имя пользователя объекту window через props.history.push () и использую room_name, полученное через props.history.location.state.room_name , для навигации по Параметры URL. Но когда я нажимаю отправить в компоненте CreateRoom, react отображает домашний компонент, установленный в route, "/" но отображается URL-адрес, "/set-user-name" который является URL-адресом компонента SetUsername. Итак, поведение, которого я хочу добиться, заключается в том, что после передачи room_name через props я использую это room_name в другом компоненте для перехода к компоненту window через SetUsername через параметры URL , но при этом также передаю имя пользователя через props компоненту window.

Ниже приведен console.log (props), когда я нажимаю отправить в компоненте CreateRoom.

 {history: {…}, location: {…}, match: {…}, staticContext: undefined}
history:
action: "PUSH"
block: ƒ block(prompt)
createHref: ƒ createHref(location)
go: ƒ go(n)
goBack: ƒ goBack()
goForward: ƒ goForward()
length: 7
listen: ƒ listen(listener)
location: {pathname: "/set-user-name", state: {…}, search: "", hash: "", key: "8gq7s3"}
push: ƒ push(path, state)
replace: ƒ replace(path, state)
__proto__: Object
location:
hash: ""
key: "o7exh2"
pathname: "/create-room"
search: ""
state: undefined
__proto__: Object
match:
isExact: true
params: {}
path: "/create-room"
url: "/create-room"
__proto__: Object
staticContext: undefined
__proto__: Object
  

App.js

     const App = () => {
      return (
        <Router>
          <Switch>
            <Route path="/create-room" component={CreateRoom} />
            <Route path="/" component={Nav} />
            <Route path="set-user-name" component={SetUsername} />
 <Route path="/:room" component={Window} />
          </Switch>
        </Router>
      );
    };
    
    ReactDOM.render(<App />, document.getElementById("root"));
  

createRoom.js

 import React from "react";
import { withRouter } from "react-router-dom";
const CreateRoom = (props) => {
  console.log(props);
  const [state, setState] = React.useState({});
  return (
    <div className="center-wrapper">
      <input
        className="room-input"
        placeholder="Room Name"
        onChange={(event) => {
          setState({ [event.target.name]: event.target.value });
        }}
        name="room"
      />
      <div
        className="btn"
        onClick={() => {
          props.history.push({
            pathname: `/set-user-name`,
            state: { room_name: state.room },
          });
        }}
      >
        Create Room
      </div>
    </div>
  );
};

export default withRouter(CreateRoom);
  

SetUsername.js

 import React from "react";
import { withRouter } from "react-router-dom";
import InputForm from "./InputForm.js";

var room_name = "DEFAULT_USERNAME";

const SetUsername = (props) => {
  console.log(props);
  React.useEffect(() => {
    room_name = props.history.location.state.room_name;
  }, []);
  const [username, SetUsername] = React.useState({});
  const handleChange = (event) => {
    SetUsername({ [event.target.name]: event.target.value });
  };
  const handleSubmit = () => {
    props.history.push({
      pathname: `/${room_name}`,
      state: { username: username.username },
    });
  };
  return (

    <InputForm
      inp_placeholder={"Enter a display name"}
      pass_placeholder={undefined}
      inp_className={"for-input"}
      pass_className={undefined}
      onChange={handleChange}
      onClick={handleSubmit}
      inputName={"username"}
      passName={undefined}
      inputRequired={true}
      passRequired={false}
      buttonText={"submit"}
    />
  );
};

export default withRouter(SetUsername);
  

Ответ №1:

В вашем компоненте SetUsername.js у вас есть то же имя из компонента, const SetUsername = (props) => что и у функции состояния в [username, SetUsername] = React.useState({}) . Я предлагаю изменить на setUsername .

Другая проблема, которую я вижу, связана с наличием переменной var room_name = "DEFAULT_USERNAME"; . Это не очень хороший шаблон и создаст проблему для вашего приложения.

У меня есть эта изолированная среда с хорошим примером обработки с react-router с помощью хуков. https://codesandbox.io/s/simple-example-using-react-router-2yovb?file=/src/App.js