如何在提交后隐藏表单,目前您必须单击切换按钮

How to hide a form after submit in react, currently you have to click a toggle button

目前我正在渲染一个歌曲列表,其中有一个切换按钮,我制作了一个切换按钮来渲染一个表单来添加一首歌曲。我怎样才能在提交该表单时隐藏该表单而无需单击按钮。我试图制作一个 useEffect 来触发该功能,但我无法破解它。提前致谢。

歌曲列表

import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { deleteSong, getSongs, updateSong } from '../../store/song';

import ReactAudioPlayer from 'react-audio-player';
import { useHistory } from 'react-router';
import SongForm from '../AddSongForm';
import EditSongForm from '../EditSongForm';
import SpecificSong from '../SpecificSong';

const SongList = () => {

    const [addShowForm, setAddShowForm] = useState(false);
    // const [editShowForm, setEditShowForm] = useState(false);

    const history = useHistory()
    const dispatch = useDispatch();

    const songsObj = useSelector((state) => state.songState.entries);
    const songs = Object.values(songsObj)

    const user = useSelector((state) => state.session.user);
    const CurrentUserId = user?.id

    const remove = (e) => {
        dispatch(deleteSong(e.target.id));
    }


    const addFormCheck = (e) => {
        if (addShowForm) setAddShowForm(false)
        if (!addShowForm) setAddShowForm(true)
    }
    // const editFormCheck = (e) => {
    //     if (editShowForm) setEditShowForm(false)
    //     if (!editShowForm) setEditShowForm(true)
    // }

    useEffect(() => {
        dispatch(getSongs());
    }, [dispatch]);


    return (
        <div>
            <div>
                <button onClick={addFormCheck}>add a song</button>
                {addShowForm ?
                    <SongForm />
                    : null}
            </div>
            <h1>Song List</h1>
            <ol>
                {songs.map(({ id, songName, songLink, userId }) => (
                    <div>
                        <SpecificSong id={id} songName={songName} songLink={songLink} userId={userId} />
                    </div>
                ))}
            </ol>
        </div>
    );
};
export default SongList;

以及正在渲染的组件

import { useState } from "react";
import { useDispatch } from "react-redux";

import { postSong } from "../../store/song";

import { useSelector } from "react-redux";



import Axios from 'axios'

const SongForm = () => {
    const dispatch = useDispatch();

    const [songName, setSongName] = useState("");
    const [songLink, setSongLink] = useState("");
    const [errors, setErrors] = useState([]);

    const [songSelected, setSongSelected] = useState("")

    const reset = () => {
        setSongName("");
        setSongLink("");

    };
    const user = useSelector((state) => state.session.user);
    const userId = user?.id

    let url;

    const handleSubmit = async (e) => {
        e.preventDefault();

        const formData = new FormData()
        formData.append('file', songSelected)
        formData.append('upload_preset', 'd3gthd7l')

        if (songSelected === '') {
            setErrors(['You have to upload an audio file!'])
        }

        Axios.post("https://api.cloudinary.com/v1_1/dyhfkvy6u/video/upload", formData).then(async (response) => {
            if (response.data.url) url = response.data.url
            const newSong = {
                songName,
                songLink: url,
                userId
            };
            const song = await dispatch(postSong(newSong))
                .catch(async (res) => {
                    const data = await res.json()
                    if (data && data.errors) setErrors(data.errors)
                })


        })

        // reset();
    };


    return (
        <div className="inputBox">
            <h1>Add A Song</h1>
            <ul>
                {errors.map((error, idx) => <li className='errors' key={idx}>{error}</li>)}
            </ul>
            <form onSubmit={handleSubmit}>
                <input
                    type="text"
                    onChange={(e) => setSongName(e.target.value)}
                    value={songName}
                    placeholder="Song Name"
                    name="Song Name"
                />
                <input
                    type='file'
                    onChange={(e) => { setSongSelected(e.target.files[0]) }}
                    placeholder="Song Link"
                    name="Audio File"
                />
                <button type="submit">Submit</button>


            </form>
        </div>
    );
};

export default SongForm;

您可以将 setAddShowForm 函数作为 prop 传递给表单,并在提交后更新其状态(请注意,您可以使用 && 进行条件渲染):

<div>
  <button onClick={addFormCheck}>add a song</button>
  {addShowForm && <SongForm setAddShowForm={setAddShowForm}/>}
</div>

将您的组件声明更改为

const SongForm = ({ setAddShowForm }) => {

并在handleSubmit方法中更新状态:

const handleSubmit = async (e) => {
    e.preventDefault();
  
    const formData = new FormData();
    formData.append('file', songSelected);
    formData.append('upload_preset', 'd3gthd7l');
  
    if (songSelected === '') {
      setErrors(['You have to upload an audio file!']);
    }
  
    Axios.post(
      'https://api.cloudinary.com/v1_1/dyhfkvy6u/video/upload',
      formData
    ).then(async (response) => {
      if (response.data.url) url = response.data.url;
      const newSong = {
        songName,
        songLink: url,
        userId,
      };
      const song = await dispatch(postSong(newSong)).catch(async (res) => {
        const data = await res.json();
        if (data && data.errors) setErrors(data.errors);

        // Hide the form 
        setAddShowForm(false);
      });
    });
  };  

您无法通过调度变量更改来触发 useEffect。 Dispatch 是一个钩子,一旦调用就不会改变。您需要创建一个状态变量 useState 并在 handleChange 上更改其值,当您这样做时,将该变量包含在 useEffect 而不是 dispatch 上,这将触发 useEffect 内容。