简体   繁体   English

反应异步状态管理

[英]React async state management

I hate to upload a code snippet with no sandbox, but this particular instance I use firebase so wasn't sure how to make one.我讨厌上传没有沙箱的代码片段,但是这个特定的实例我使用了 firebase,所以不确定如何制作一个。 Apologies for the verbose code.为冗长的代码道歉。 I'm a beginner React developer and I've been stuck on this state management issue for 2 weeks now, and I tried so many different methods but to no fruit.我是一名初级 React 开发人员,我已经被这个状态管理问题困住了 2 周,我尝试了很多不同的方法,但没有结果。 Please help.请帮忙。

My goal is to click AddLinkButton to make multiple input forms one by one, each input form would be different links, and by clicking Apply Button it would collect all the link values and store it to firebase's firestore.我的目标是单击AddLinkButton一个接一个地制作多个输入表单,每个输入表单将是不同的链接,通过单击Apply Button ,它将收集所有链接值并将其存储到 firebase 的 firestore。 Once the storing is complete, it would display a preview by passing in multiple updated hook values to <UserPreview /> .存储完成后,它将通过将多个更新的钩子值传递给<UserPreview />来显示预览。

If I run this particular code below, the key which is supposed to be the value of the link input forms, is null and does not update on onChange.如果我在下面运行此特定代码,则应该是链接输入表单的值的键为 null,并且不会在 onChange 上更新。

Please help... much appreciated.请帮助...非常感谢。 Thank you.谢谢你。

EDIT: changed variable name key to keyHook but to no success.编辑:将变量名称键更改为 keyHook 但没有成功。 Same issue同样的问题

const AdminCustomizer = () => {
  const [username, setUsername] = useState(null);
  const [linkForm, setlinkForm] = useState([]);
  const [spotlightLabel, setSpotlightLabel] = useState('');
  const [spotlightLink, setSpotlightLink] = useState('');
  const [refresh, setRefresh] = useState(false);
  const [keyHook, setKeyHook] = useState(null);
  const [startCollect, setStartCollect] = useState(false);
  const linkRef = useRef();
  const userInfo = {username, linkRef, spotlightLabel, spotlightLink, pfpURL, refresh};

  // on initial load, load database to page
  if (!username) {
    firebase.getAuth().onAuthStateChanged(user => {
      if (user) {
        setUsername(user.displayName);
        firebase.getUserInfo(user.displayName).then(result => {
          setSpotlightLabel(result.spotlightLabel);
          setSpotlightLink(result.spotlightLink);
          linkRef.current = result.links;
          if (result.links) {
            Object.values(result.links).forEach(link => {
              AddLinks(link);
            });
          }
        })
      }
    });
  }

  //on refresh (when clicking apply changes button) reload page values with updated database
  useEffect(() => {
    if (refresh) {
      firebase.getAuth().onAuthStateChanged(user => {
        if (user) {
          firebase.getUserInfo(user.displayName).then(result => {
            linkRef.current = result.links;
            Object.values(result.links).forEach(link => {
              AddLinks(link);
            });
          })
          setRefresh(false);
        }
      });
    }
  }, [refresh])
  
  // adding AddLink button will add a new input form
  // adding AddLink with firebase database value will add a new input form with values loaded
  const AddLinks = url => {
    const hooks = { refresh, startCollect, keyHook, setKeyHook };
    if (url) setKeyHook(url);
    setlinkForm([ ...linkForm, <AddLink key={keyHook} keyHook={keyHook} hooks={hooks} /> ]);
  }

  // add link input form
  const AddLink = props => {
    const handleChange = e => setKeyHook(e.target.value);
    return (
      <form noValidate autoComplete="off">
        <br />
        <Link label="Social" onChange={handleChange} value={props.keyHook} /> 
      </form>
    )
  }
  
  // when apply changes is clicked, collect input values from all link input forms
  if (startCollect) { 
    linkForm.forEach(form => {
      linkRef.current = { 
        ...linkRef.current,
        link: form.keyHook,
      }
    });
    firebase.addLinksToUser({ spotlightLabel, spotlightLink, linkRef }).then(() => {
      //force refresh to update userInfo for UserPreview
      setStartCollect(false);
      setRefresh(true);
    });
  }

  return (
      <>
        <LinkBox>
          <ApplyButton onClick={() => setStartCollect(true)}>Apply Changes</ApplyButton>
          <Link label="Website Title" onChange={e => setSpotlightLabel(e.target.value)} value={spotlightLabel} />
          <Link label="Website URL" onChange={e => setSpotlightLink(e.target.value)} value={spotlightLink}/>
          <AddLinkButton onClick={() => AddLinks(null)} />
          <div>{linkForm ? linkForm.map(child => child) : null}</div>
        </LinkBox>
          <div>
            <PhoneOutline>
              <UserPreview userInfo={userInfo}/>
            </PhoneOutline>
          </div>
      </>
  );
}

export default AdminCustomizer;

In AddLink , the key is a restricted keyword and doesn't get propagated as props.AddLinkkey是受限制的关键字,不会作为道具传播。 Try a different prop name instead of key .尝试使用不同的道具名称而不是key

See this link这个链接

Try:尝试:

<AddLink key={keyHook} keyHook={keyHook} hooks={hooks} />

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

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