Jordan
Jordan

Reputation: 103

React passing props to other components

Hello I am having trouble passing props between components. I can't share the exact code so I made a simplified version. I am not getting any console errors, though login is obviously 'undefined' Any insight is appreciated!

App.js

import React, { useState } from "react";


function App() {
  
 
  const [login, setLogin] = useState('Jpm91297');

  const changeState = () => {
    const newLogin = document.getElementById('loginData').value;
    setLogin(newLogin);
  }

  return (
    <>
      <h1>Fancy API Call!!!</h1>
      <form onSubmit={() => changeState()}>
          <input type='text' id='loginData'></input>
          <button>Submit</button>
      </form>
    </>
  );
}

export default App;

Api.Js

import React, {useEffect, useState} from "react";

const Api = ( { login } ) => {
    const [data, setData] = useState(null);
    
    
    useEffect(() => {
        fetch(`https://api.github.com/users/${login}`)
          .then((res) => res.json())
          .then(setData);
      }, []);
    
      if (data) {
        return <div>{JSON.stringify(data)}</div>
      }
    
      return <div>No data Avail</div>

}

export default Api;

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Api from './api'

ReactDOM.render(
    <>
    <App />
    <Api />
    </>,
    
   
  document.getElementById('root')
);

Upvotes: 1

Views: 475

Answers (1)

Drew Reese
Drew Reese

Reputation: 202751

  1. You are not preventing the default form action from occurring. This reloads the app.
  2. You should lift the login state to the common parent of App and Api so it can be passed down as a prop. See Lifting State Up.

Example:

index.js

Move the login state to a parent component so that it can be passed down as props to the children components that care about it.

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Api from './api';

const Root = () => {
  const [login, setLogin] = useState('Jpm91297');

  return (
    <>
      <App setLogin={setLogin} />
      <Api login={login} />
    </>
  );
};

ReactDOM.render(
  <Root />,
  document.getElementById('root')
);

App

Pass the changeState callback directly as the form element's onSubmit handler and prevent the default action. Access the form field from the onSubmit event object.

function App({ setLogin }) {
  const changeState = (event) => {
    event.preventDefault();
    const newLogin = event.target.loginData.value;
    setLogin(newLogin);
  }

  return (
    <>
      <h1>Fancy API Call!!!</h1>
      <form onSubmit={changeState}>
        <input type='text' id='loginData'></input>
        <button type="submit">Submit</button>
      </form>
    </>
  );
}

Api

const Api = ({ login }) => {
  const [data, setData] = useState(null);
    
  useEffect(() => {
    fetch(`https://api.github.com/users/${login}`)
      .then((res) => res.json())
      .then(setData);
  }, [login]); // <-- add login dependency so fetch is made when login changes
    
  if (data) {
    return <div>{JSON.stringify(data)}</div>;
  }
    
  return <div>No data Avail</div>;
};

Edit react-passing-props-to-other-components

enter image description here

Upvotes: 2

Related Questions