简体   繁体   English

如何在状态更改时重新渲染功能组件?

[英]How to rerender functional component on state change?

I want my functional component to rerender when the state "dataRes" changes.我希望我的功能组件在状态“dataRes”更改时重新呈现。 The code below is the whole component but on first login I have to reload manually to display the avatar/username etc.下面的代码是整个组件,但在第一次登录时,我必须手动重新加载以显示头像/用户名等。

As soon as "loggedin" changes to "true" it should rerender and display username.一旦“loggedin”更改为“true”,它应该重新呈现并显示用户名。 Well the displaying works perfectly fine just the first rerender doesn't...好吧,显示效果非常好,只是第一次重新渲染不...

Component:成分:

function Username() {
  const cookies = new Cookies();

  const [username, setUsername] = useState(false);
  const [loading, setLoading] = useState(true);
  const [shortened, setShortened] = useState(false)
  const authLink = "https://discord.com/api/oauth2/authorize?client_id=" + clientID + "&redirect_uri=" + clientRedirect + "&response_type=code&scope=identify%20guilds"
  const [loggedin, setLoggedin] = useState(false);
  const history = useHistory();
  const [data, setData] = useState(null);
  const [dataRes, setDataRes] = useState(false);

  useEffect(() => {
    fetch('SomeAPIUrlHere', {
      method: "POST",
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ token: cookies.get("someCookie") })
    })
    .then((res) => res.json())
    .then((data) => {
      setData(data)
      setDataRes(true)
    })
  }, []);

  try {
    if(dataRes !== false) {
      if(data.username) {
        if(username != data.username){
          if(data.username.length > 10) {
            setShortened(true)
          }
          setDataRes(false)
          setUsername(true)
          setLoggedin(true)
          setLoading(false)
        }
      }
    }
  } catch(error) {
    console.log(error)
  }

  useEffect(() => {
    setTimeout(() => {
      setLoading(false)
    }, 1000)
  }, [])

  const SignOut = () => {
    const cookies = new Cookies();
    cookies.remove("us_au_tok")
    history.push("/")
    window.location.reload(false)
  }

  return(
    <div className="flex float-left">
      <a href={loggedin === false ? authLink : "/dashboard"} className={loggedin === false ? "shadow-2xl text-center  text-white bg-gray rounded-2xl p-2 lg:px-5 md:px-5 sm:pl-3.5 xs:pl-3.5 mr-2 block lg:w-40 md:w-40" : "text-center text-white  rounded-2xl p-2 lg:px-5 md:px-5 sm:pl-3 xs:pl-3 mr-2 block lg:w-48 md:w-48"}>
        <div className={loading === true ? "md:w-8 lg:w-8 sm:w-7 xs:w-7 m-auto text-center" : "m-auto text-center"}>
          <div className="flex justify-nter">
            {loggedin === true ? <img src={"https://cdn.discordapp.com/avatars/" + data.userid  + "/" + data.avatar + ".png?size=1024"} alt="Useravatar" className="lg:max-h-50 md:max-h-50 sm:max-h-35 xs:max-h-35 rounded-full mr-2"></img> : ""}
            {loading === true ? <img src={LoadingSVG} alt='Loading Animation'/> : <p className="hover:text-brightgray duration-300 lg:m-auto md:m-auto sm:my-auto xs:my-auto">{loggedin === true ? <span>{shortened === false ? data.username : data.username.substring(0, 10) + "..."}</span> : "Login"}</p> }
          </div>
        </div>
      </a>
      {loggedin === true ? <button onClick={SignOut}><FontAwesomeIcon icon={faSignOutAlt} className="text-white mr-4" title="Sign Out" /></button> : ""}
    </div>
  )
};

You should pass dataRes as second argument to useEffect您应该将dataRes作为第二个参数传递给useEffect

The second argument to useEffect is an array of dependencies . useEffect 的第二个参数是一个依赖项数组。 If you want to control when effect is to be executed after mounting the component, then pass an array of dependencies as the second argument如果你想控制挂载组件后什么时候执行 effect,那么传递一个依赖数组作为第二个参数

here is a sample:这是一个示例:

 const {useEffect,useState} = React; function App () { const [data, setData] = useState(null); const [dataRes, setDataRes] = useState(false); useEffect(() => { if (dataRes) { fetch("https://gorest.co.in/public/v1/users", { method: "GET" }) .then((res) => res.json()) .then((data) => { setData(data); //setDataRes(true); }); } else { setData([]); } }, [dataRes]); const handleClick = () => { setDataRes((prev) => !prev); }; return ( <div className="App"> <button onClick={handleClick}>change dataRes</button> <div>{`dataRes: ${dataRes}`}</div> <hr /> <div>{JSON.stringify(data)}</div> </div> ); } ReactDOM.render( <App/> , document.getElementById("root") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM