javascript - I am passing the state to a function component via history (react-router-dom) but it says the state is 'null' - TagMerge
3I am passing the state to a function component via history (react-router-dom) but it says the state is 'null'I am passing the state to a function component via history (react-router-dom) but it says the state is 'null'

I am passing the state to a function component via history (react-router-dom) but it says the state is 'null'

Asked 9 months ago
1
3 answers

You need to use your history like this for react-router v6.

history("/session/verifyotp", {
  state: { serverMessage: serverMessage },
});

Check the Documentation. It accepts to and the state as an optional param.

Here is my componentA

import {useNavigate} from 'react-router-dom';

const ComponentA = (props) => {
  const navigate = useNavigate();
  const toComponentB = () => {
    navigate("/componentB", { state: { id: 1, name: "sabaoon" } });
  };
  return (
    <button
      onClick={() => {
        toComponentB();
      }}
    >
      Component B
    </button>
  );
};

export default ComponentA;

You can get the state data in componentB like this.

import { useLocation } from "react-router-dom";

function ComponentB() {
  const location = useLocation();
  return <div>{location?.state?.name}</div>;
}

export default ComponentB;

You can update your handleFormSubmit method like this. You are using both async/await and .then which confuses the users.

const handleFormSubmit = async (event) => {
  event.preventDefault();
  console.log(formData);
  let newValue;
  try {
    const response = await axios.post(
      `http://localhost:4000/accounts/register`,
      formData
    );
    console.log(response);
    console.log(response.data);
    newValue = response.data;
    setServerMessage(newValue);
  } catch (error) {
    console.log(error);
  }
  history({
    pathname: "/session/verifyotp",
    state: { serverMessage: newValue },
  });
};

Source: link

0

App.js
import React, { Component } from 'react';
import './App.css';
import TodoList from './components/TodoList.js'
import VisabilityFilter from './components/VisabilityFilter.js'

export const SHOW_ALL = 'show_all'
export const SHOW_COMPLETED = 'show_completed'

class App extends Component {
  constructor (props) {
    super(props)

    this.state = {
      inputValues: {
        'newTodo': ''
      },
      todos: [
        {
          task: 'My First Todo',
          completed: false
        }
      ],
      visabilityFilter: SHOW_ALL
    }

    this.addTodo = this.addTodo.bind(this)
    this.handleInputChange = this.handleInputChange.bind(this)
    this.handleKeyUp = this.handleKeyUp.bind(this)
    this.toggleCompleted = this.toggleCompleted.bind(this)
    this.removeTodo = this.removeTodo.bind(this)
    this.checkCompleted = this.checkCompleted.bind(this)
    this.setVisabilityFilter = this.setVisabilityFilter.bind(this)

  }

  handleInputChange (e) {
      const { inputValues } = this.state
      const { id, value } = e.target
      this.setState({
        inputValues: {
          ...inputValues,
          [id]: value
        }
      })
  }

  handleKeyUp (e) {
    var code = e.key
        if(code === 'Enter') {
          this.addTodo(e);
        }
  }

  toggleCompleted (e, index) {
    const { todos } = this.state

    todos[index].completed = !todos[index].completed

    todos.sort((a, b) => b.completed - a.completed)

    this.setState({ todos })
  }

  removeTodo (e, index) {
    const { todos } = this.state
    this.setState ({ todos: todos.filter((todo, i) => i !== index) })
  }

  addTodo (e) {
      const { todos, inputValues } = this.state
      const { dataset } = e.target

      if (inputValues[dataset.for] === '') return

      const newTodo = { task: inputValues[dataset.for], completed: false }
      todos.push(newTodo)

      this.setState({
        todos,
        inputValues: { ...inputValues, [dataset.for]: '' }
      })
  }

  checkCompleted (e, index) {
    const { todos } = this.state
    return { todos } && todos[index].completed
  }

  setVisabilityFilter (e) {
    const { visabilityFilter } = this.state
    const { dataset } = e.target

    this.setState({
      visabilityFilter: dataset.for
    })

    console.log ({ visabilityFilter })
  }

  render() {
    const { todos, inputValues, visabilityFilter } = this.state
    return (
      <div className="App">
        <TodoList
          todos={todos}
          inputValues={inputValues}
          addTodo={this.addTodo}
          handleInputChange={this.handleInputChange}
          removeTodo={this.removeTodo}
          toggleCompleted={this.toggleCompleted}
          handleKeyUp={this.handleKeyUp}
          checkCompleted={this.checkCompleted}
        />
        <VisabilityFilter setVisabilityFilter={this.setVisabilityFilter} />
      </div>
    );
  }
}

export default App;
VisabilityFilter.js
import React from 'react'
import { func } from 'prop-types'

import { SHOW_ALL, SHOW_COMPLETED } from '../App'

const VisabilityFilter = props => {
  return (
    <div>
      <button data-for={SHOW_COMPLETED} onClick={ props.setVisabilityFilter } >
        Show Completed Tasks
      </button>
      <button data-for={SHOW_ALL} onClick={ props.setVisabilityFilter }>
        Show All Tasks
      </button>
    </div>
  )
}

VisabilityFilter.propTypes = {
  setVisabilityFilter: func.isRequired
}

export default VisabilityFilter
setState() is async (React docs), so the state changes won't be applied immediately. If you want to log out the new state,setState() takes in a function as the second argument and performs that function when the state is updated. So:
this.setState({ 
    abc: xyz 
  }, 
  () => console.log(this.state.abc),
)
In the functional components use useEffect to track for changes of state.
useEffect(() => {
       console.log(someState);
  },[someState);

Source: link

0

With client side routing, developers are able to manipulate the browser history stack programmatically. For example, we can write some code like this to change the URL without the browsers default behavior of making a request to the server:
<a
  href="/contact"
  onClick={(event) => {
    // stop the browser from changing the URL and requesting the new document
    event.preventDefault();
    // push an entry into the browser history stack and change the URL
    window.history.pushState({}, undefined, "/contact");
  }}
/>
Well, that's not totally true. We can listen for changes to the URL via pop events:
window.addEventListener("popstate", () => {
  // URL changed!
});
That's where a React Router specific history object comes into play. It provides a way to "listen for URL" changes whether the history action is push, pop, or replace.
let history = createBrowserHistory();
history.listen(({ location, action }) => {
  // this is called whenever new locations come in
  // the action is POP, PUSH, or REPLACE
});
The browser has a location object on window.location. It tells you information about the URL but also has some methods to change it:
window.location.pathname; // /getting-started/concepts/
window.location.hash; // #location
window.location.reload(); // force a refresh w/ the server
// and a lot more
Instead of using window.location, React Router has the concept of a location that's patterned after window.location but is much simpler. It looks like this:
{
  pathname: "/bbq/pig-pickins",
  search: "?campaign=instagram",
  hash: "#menu",
  state: null,
  key: "aefz24ie"
}

Source: link

Recent Questions on javascript

    Programming Languages