using getElementByID in React

无人久伴 提交于 2021-02-11 07:11:57

问题


I am getting a "Cannot read property 'style' of null" on my getElementById('password'), but its clearly defined on the page. I'm new to react, and I'm guessing this isn't allowed or something. But I'm trying to have the password page show until, its style is changed to "none", which happens in a different component.

function App() {
  const [loggedIn, setLoggedIn] = useState(false)

  if (document.getElementById('password').style.display = "block"){
    setLoggedIn(false)
  } else {
    setLoggedIn(true)
  }

  return (
    <div className="app">
      { //Check if message failed
        (loggedIn)
          ? <div> <Password /> </div> 
          : <div> 
              <Nav />
              <div id="allFiles">
                <FileEarth title="Earth Update"/>
                <FileMars title="Mars Rover Update"/>
                <HardDrvie title="ASTRO Entertainment"/>
                <Folder title="Moon Pics"/>
              </div>
            </div> 
      } 
    </div>
  );
}

export default App;


回答1:


By defined on the page, it seems like you only have this component <Password /> that is related to "password". Since you are using getElementById(), you will need to be able to define the id of the element like <Password id="password" /> and pass down props into the component which will then assign the id as such.

Also p.s. you have HardDrvie instead of HardDrive




回答2:


A few things that could help you out:

  1. It is preferred to use refs to get access to DOM elements in React.
  2. When rendering a component React creates a representation of your app in it's virtual DOM and then diffs this against the actual DOM so that it minimises DOM updates that are expensive. This means that at the point you are attempting to use 'getElementById()` the element has not yet been added to the DOM.
  3. You are using a function component which will result in your inline logic being run every time the component re-renders. To avoid rerunning this logic that should only run once it should be wrapped in a useEffect or less often a useLayoutEffect (see the docs for more information).

From what I can see a callback function should be able to do what you want:

// The password component gets passed the callback function as a prop.
// In this case the callback function would be onLogin.
// When clicking the div the callback function that was provided by
// the parent will be called and the state on the parent will be 
// updated.
const Password = ({ onLogin }) => {
    return (
        <div
            onClick={onLogin}
        >
            Login
        </div>
    );
}

// Parent component.
const Parent = () => {
    // Create state to store if the user is logged in or not.
    const [loggedIn, setLoggedIn] = React.useState(false);

    // Create callback function to pass to the Password component.
    // useCallback ensures that the function is only recreated when
    // a variable in the dependency array is updated.
    // The dependency array uses a reference compare to check for changes.
    const onLogin = React.useCallback(() => {
        setLoggedIn(true);
    }, [setLoggedIn] /* Dependency Array - recreate on setLoggedIn change */ );


    return (
        <>
            <div>
                {/* Write out loggedIn value for debugging. */}
                { loggedIn ? "Logged In" : "Not Logged In" }
            </div>
            {/* Conditionally render password component passing onLogin */}
            { !loggedIn && <Password onLogin={onLogin} /> }
        </>
    )
}


来源:https://stackoverflow.com/questions/64980022/using-getelementbyid-in-react

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!