использование getElementById в React

#reactjs #dom #jsx

#reactjs #dom #jsx

Вопрос:

Я получаю сообщение «Не удается прочитать свойство ‘style’ null» в моем getElementById (‘password’), но оно четко определено на странице. Я новичок в react, и я предполагаю, что это запрещено или что-то в этом роде. Но я пытаюсь отобразить страницу пароля до тех пор, пока ее стиль не будет изменен на «none», что происходит в другом компоненте.

 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:

По определению на странице кажется, что у вас есть только этот компонент <Password /> , связанный с «паролем». Поскольку вы используете getElementById() , вам нужно будет иметь возможность определять идентификатор элемента like <Password id="password" /> и передавать реквизиты в компонент, который затем назначит идентификатор как таковой.

Также p.s. у вас есть HardDrvie вместо HardDrive

Ответ №2:

Несколько вещей, которые могут вам помочь:

  1. Предпочтительно использовать ссылки для получения доступа к элементам DOM в React.
  2. При рендеринге компонента React создает представление вашего приложения в его виртуальном DOM, а затем сравнивает его с фактическим DOM, чтобы свести к минимуму дорогостоящие обновления DOM. Это означает, что в тот момент, когда вы пытаетесь использовать ‘getElementById ()`, элемент еще не был добавлен в DOM.
  3. Вы используете функциональный компонент, который приведет к запуску вашей встроенной логики при каждом повторном рендеринге компонента. Чтобы избежать повторного запуска этой логики, которая должна выполняться только один раз, ее следует обернуть в a useEffect или реже a useLayoutEffect (см. Документы для получения дополнительной информации).

Из того, что я вижу, функция обратного вызова должна быть способна делать то, что вы хотите:

 // 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 amp;amp; <Password onLogin={onLogin} /> }
        </>
    )
}
 

Комментарии:

1. Хороший! Хотя я не думаю, что useCallback здесь необходим на 100% и может фактически снизить производительность, добавив его. Вместо этого, вероятно, было бы проще и эффективнее просто иметь const handleLogin = () => setLoggedIn(true) . Вот несколько статей, в которых вы можете прочитать больше об этом: atomizedobjects.com/blog/react /… и kentcdodds.com/blog/usememo-and-usecallback