简体   繁体   English

如何触发用户在 React 中输入的数据的呈现?

[英]How to trigger of the render of data that a user inputs in React?

In this App, student data is pulled from an API, new Tags can be added for each student by clicking the PLUS button on a card.在这个应用程序中,学生数据是从 API 中提取的,可以通过单击卡片上的加号按钮为每个学生添加新标签。

ISSUE: the tags DON'T render on the screen immediately after they are inputed.问题:标签在输入后不会立即呈现在屏幕上。 They will only render after the drop down is closed and opened again or if a number of tags are entered consecutively.它们只会在下拉菜单关闭并再次打开或连续输入多个标签后呈现。

The project and code can be found here: https://codesandbox.io/s/hatch-frontend-mch-52n67?file=/src/components/views/Card.js:2280-2320项目和代码可以在这里找到: https://codesandbox.io/s/hatch-frontend-mch-52n67?file=/src/components/views/Card.js:2280-2320

Card.js Card.js

// ...

// Submit Handler function:
const submitNewTagHandler = (e) => {
    e.preventDefault();
    setHasTags(true);
    console.log(tags);
    setHeightState(
       `${content.current.scrollHeight}px`
    );
    setTags([...tags, newTag]);
    updateStudents(tags, index);
    setNewTag('');
  };


//Tag render:
{hasTags && <Tags student={student} />}
// Tag input:
<form onSubmit={submitNewTagHandler}>
    <input
    className='​add-tag-input​'
    onChange={(e) => setNewTag(e.target.value)}
    value={newTag}
    type='text'
    placeholder='Add a new tag'
    />
</form>

App.js应用程序.js

// updateStudent is called as update in App.js
// (This updates the main data array called students)
const update = (t, index) => {
    setTags(t);
    setStudents(
      students.map((student, i) => {
        // console.log(i, index);
        if (i === index) {
          console.log(student, tags);
          return { ...student, tags };
        } else {
          return student;
        }
      })
    );
    console.log(students);
  };

Tags.js标签.js

const Tags = (props) => {
  return (
    <div className='tags'>
      {props.student.tags.map((tag, index) => {
        return (
          <h3 className='tag' key={index}>
            {tag}{' '}
          </h3>
        );
      })}
    </div>
  );
};

I've tried different ways to use useEffect to re-render the tags but have been unsuccessful thus far…我尝试了不同的方法来使用 useEffect 重新渲染标签,但到目前为止都没有成功……

Thanks!谢谢!

Okay because of how you setNewTags using local state, and then you passing props to Tags, you causing sync errors, since react states are all async.好的,因为您如何使用本地 state setNewTags,然后将道具传递给标签,您会导致同步错误,因为反应状态都是异步的。

So I updated the codes to useRef to get current values and it should work.因此,我将代码更新为 useRef 以获取当前值,它应该可以工作。

There's many many changes to be made.有很多很多的改变要做。 Basically your codes are all messed up because you are updating state with another state.基本上你的代码都搞砸了,因为你正在用另一个 state 更新 state。 (eg u updating tags with new tags), but newtags has not been updated with new value. (例如,您使用新标签更新标签),但新标签尚未更新为新值。

I've also removed your useEffect in App.js, and showed you how to useMemo instead.我还在 App.js 中删除了你的 useEffect,并向你展示了如何改用 useMemo。

Delete these 2 lines删除这两行

  const [tags, setTags] = useState(student.tags);
  const [newTag, setNewTag] = useState('');

Create new input Ref创建新的输入参考

  const inputRef = useRef()
  const formRef = useRef()

Change input to this将输入更改为此

       <input
          className='​add-tag-input​'
          ref = {inputRef} //add this
          //value={newTag} remove this
          type='text'
          placeholder='Add a new tag'
        />

then your handle submit function然后你的句柄提交 function

  const submitNewTagHandler = (e) => {
    const value = inputRef.current.value
    e.preventDefault();
    setHeightState(
       `${content.current.scrollHeight}px`
    );
    updateStudents([...student.tags, value], index);
    formRef.current.reset()
  };

then change this line to the updated line.然后将此行更改为更新的行。

{student?.tags?.length > 0 && } {学生?.tags?.length > 0 && }

Then you need to update your.map with a key else it's not rendering correctly.然后您需要使用密钥更新您的.map,否则无法正确渲染。

<Card key={`student-${student.id}`} students={props.students} student={student} index={index} updateStudents={props.updateStudents} />

In your update function在您的更新 function

const update = (t, index) => {
    setTags(t);
    setStudents((prev) =>
      prev.map((student, i) => {
        // console.log(i, index);
        if (i === index) {
          console.log("prev map", student, t);
          return { ...student, tags: t };
        } else {
          return student;
        }
      })
    );
    console.log(students);
  };

Update component to this将组件更新为此

const Tags = ({ tags }) => {
  return (
    <div className="tags">
      {tags.map((tag, index) => {
        return (
          <h3 className="tag" key={`tag-${index}`}>
            {tag}{" "}
          </h3>
        );
      })}
    </div>
  );
};

Add this to fix your accordion where input become hidden.添加这个来修复你的手风琴输入被隐藏的地方。

 useEffect(() => {

    if (setActive) setHeightState(`${content.current.scrollHeight}px`);

  },[props])

There's too many changes made.改动太多了。 I may have missed out some of them here.我可能在这里错过了其中一些。 see new sandbox 查看新沙盒

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

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