Home > Back-end >  React I have a endless loop rendering my edit component
React I have a endless loop rendering my edit component

Time:05-14

I have two components. My dashbord-component, in which I am dispatching the getAllDropDownRessort, which triggers the the findAll function in my dropdownRessortSlice and an edit-component, in which I am dispatching the getDropdownRessort, which triggers the finOne function in the same slice. When I calling the edit-component, it not ends rendering, and the redux-devtools tell me that it always renders the findAll function. Thanks for your help.

Here is my dashbord-component:

const DropdownRessorts = () => {
  //bring in
  const {dropdownRessort, isLoading, isError, message} = useSelector((state)=>state.dropdownRessort);
  const dispatch = useDispatch();
  useEffect(()=>{
    if(isError){
      console.log(message);
    }
    dispatch(getAllDropdownRessort());

    return ()=>{
      dispatch(reset());
    }
  }, [dispatch, isError, message]);
//bring out
  const [formdata, setFormdata] = useState(
    {
      lis:[],
      videos:[
        {
          iframe:"",
          ressort:"",
          timestamp:"",
          theme:"",
          title:""
      },
      {
          iframe:"",
          ressort:"",
          timestamp:"",
          theme:"",
          title:""
      },
      {
          iframe:"",
          ressort:"",
          timestamp:"",
          theme:"",
          title:""
      }
      ],
      themen:[],
    }
  );
    const {lis, videos,themen} = formdata;
    
    const handleChange = (e)=>{
      setFormdata((prevState)=>({
        ...prevState,
        [e.target.name]: e.target.value,
      }))
    }

    const onSubmit = (e)=>{
      e.preventDefault();
      const dropdownRessortData = {
        lis,
        videos,
        themen,
      }
      dispatch(createDropdownRessort(dropdownRessortData));
    }
    if(isLoading){
      return <Spinner/>
    }
  return (
    <Container>
            <CrudTitleHolder>
              <CrudTitle>Dropdown Menü Ressort</CrudTitle>
            </CrudTitleHolder>
            <DataformDropDownRessort onSubmit={onSubmit}>
              {dropdownRessort.length > 0 && <DataHolder>
                {dropdownRessort.map((item)=>(
                  <div key={item._id}>
                    {console.log(item._id)}
                         <h4 id="name">{item.name}</h4>
                      <div id="listenpunkte">Menüpunkte: {item.lis.join(", ")}<span style={{color:"var(--red)"}}> Bitte nur nach Absprache verändern.</span></div>
                      <VideoWrapper>
                        <DataVideoholder>
                          <iframe src={item.videos[0].iframe} title={item.videos[0].title}/>
                          <h4>{item.videos[0].ressort}</h4>
                          <h4>{item.videos[0].theme}</h4>
                          <p>{item.videos[0].title}</p>
                        </DataVideoholder>
                        <DataVideoholder>
                          <iframe src={item.videos[1].iframe} title={item.videos[0].title}/>
                          <h4>{item.videos[1].ressort}</h4>
                          <h4>{item.videos[1].theme}</h4>
                          <p>{item.videos[1].title}</p>
                        </DataVideoholder>
                        <DataVideoholder>
                          <iframe src={item.videos[2].iframe} title={item.videos[0].title}/>
                          <h4>{item.videos[2].ressort}</h4>
                          <h4>{item.videos[2].theme}</h4>
                          <p>{item.videos[2].title}</p>
                        </DataVideoholder>
                        </VideoWrapper>
                        <Themen>Themen: {item.themen.join(", ")}</Themen>
                    <DataButtonHolder>
                          <Link to={`/dropdownressortedit/${item._id}`}className="link"> 
                      <DataUpdateButton>Update</DataUpdateButton>
                      </Link>
                      <DataDeleteButton onClick={()=>dispatch(deleteDropdownRessort(item._id))}>Löschen</DataDeleteButton>
                    </DataButtonHolder>
                  </div>
                ))}
                </DataHolder>}

                <section className="menupoints" encType="multipart/form-data">
                  <DataLabel htmlFor="lis_ressorts">Menüpunkte Ressorts</DataLabel>
                  <DataInput type="text" name="lis_ressorts" id="lis_ressorts" value={lis} onChange={handleChange}/>
                </section>
                <div className="videos">
                    <section className="video_1">
                    <DataLabel htmlFor="ressortvideo_1_iframe">Video 1</DataLabel>
                    <DataInput type="file" name="ressortvideo_1_iframe" id="video_1_iframe" 
                    style={{background:"var(--blue)", color:"var(--white)"}}
                    value={videos[0].iframe}  onChange={handleChange}/>

                    <DataLabel htmlFor="video_1_ressort">Video 1 Ressortzuordnung</DataLabel>
                    <DataInput type="text" name="video_1_ressort" id="video_1_ressort" value={videos[0].ressort} onChange={handleChange}/>

                    <DataLabel htmlFor="video_1_theme">Video 1 Themenzuordnung</DataLabel>
                    <DataInput type="text" name="video_1_theme" id="video_1_theme"  value={videos[0].theme} onChange={handleChange}/>

                    <DataLabel htmlFor="video_1_title">Video 1 Titelzuordnung</DataLabel>
                    <DataInput type="text" name="video_1_title" id="video_1_title"  value={videos[0].title} onChange={handleChange}/>
                    </section>

                    <section className="video_2">
                      <DataLabel htmlFor="ressortvideo_2_iframe">Video 2</DataLabel>
                      <DataInput type="file" name="ressortvideo_2_iframe" id="video_2_iframe" 
                      style={{background:"var(--blue)", color:"var(--white)"}}
                      value={videos[1].iframe} onChange={handleChange}/>

                      <DataLabel htmlFor="video_2_ressort">Video 2 Ressortzuordnung</DataLabel>
                      <DataInput type="text" name="video_1_ressort" id="video_2_ressort"  value={videos[1].ressort} onChange={handleChange}/>

                      <DataLabel htmlFor="video_2_theme">Video 2 Themenzuordnung</DataLabel>
                      <DataInput type="text" name="video_2_theme" id="video_2_theme" value={videos[1].theme} onChange={handleChange}/>

                      <DataLabel htmlFor="video_2_title">Video 2 Titelzuordnung</DataLabel>
                      <DataInput type="text" name="video_2_title" id="video_2_title" value={videos[1].title} onChange={handleChange}/>
                    </section>
                    <section className="video_3">
                      <DataLabel htmlFor="ressortvideo_3_iframe">Video 3</DataLabel>
                      <DataInput type="file" name="ressortvideo_3_iframe" id="video_3_iframe" 
                      style={{background:"var(--blue)", color:"var(--white)"}}
                      value={videos[2].iframe} onChange={handleChange}/>

                      <DataLabel htmlFor="video_3_ressort">Video 3 Ressortzuordnung</DataLabel>
                      <DataInput type="text" name="video_3_ressort" id="video_3_ressort"  value={videos[2].ressort} onChange={handleChange}/>

                      <DataLabel htmlFor="video_3_theme">Video 3 Themenzuordnung</DataLabel>
                      <DataInput type="text" name="video_3_theme" id="video_3_theme"  value={videos[2].theme} onChange={handleChange}/>

                      <DataLabel htmlFor="video_3_title">Video 3 Titelzuordnung</DataLabel>
                      <DataInput type="text" name="video_3_title" id="video_3_title"  value={videos[2].title} onChange={handleChange}/>
                    </section>
                </div>
                <section className="themen">
                  <DataLabel htmlFor="themen_ressorts">Themen</DataLabel>
                  <DataInput type="text" name="themen_ressorts" id="themen_ressorts" value={themen} onChange={handleChange}/>
                </section>
                <DataButtonHolder>
                  <DataSendButton type="submit">Absenden</DataSendButton>
                  </DataButtonHolder>
            </DataformDropDownRessort>
    </Container>
  )
}

export default DropdownRessorts

Here is my edit-component:

const DropdownRessortEdit = () => {
    const dispatch = useDispatch();
    const {dropdownRessort, isLoading, isError, message} = useSelector((state)=>state.dropdownRessort);
    const { id } = useParams();

    const [data, setData] = useState({
        lis: [],
        videos:[
                {
                    iframe:"",
                    ressort:"",
                    theme:"",
                    title:"",
                },
                {
                    iframe:"",
                    ressort:"",
                    theme:"",
                    title:"",
                },
                {
                    iframe:"",
                    ressort:"",
                    theme:"",
                    title:"",
                }, 
        ],
        themen:[],

    })
    const {lis, videos, themen} = data;


    useEffect(()=>{
        if(isError){
            window.alert(message);
        }
            dispatch(getDropdownRessort(id));

            return ()=>{
                dispatch(reset());
            }
        
    }, [dispatch, isError, message, id]);

   
    const updateData = (value)=>{
        return setData((prev) =>{
            return { ...prev, ...value}
        })
    }
    const onSubmit = (e)=>{
        e.preventDefault();
        const updateDropdownRessortData = {
            lis,
            videos,
            themen,
        }
        dispatch(updateDropdownRessort(updateDropdownRessortData));
    }
    if(isLoading){
        return <Spinner/>
    }
  return (
   
    <Container>
        <Navbar/>
        <TitleHolder>
            <Title>Update DropdownRessort</Title>
        </TitleHolder>
        <ContentHolder>
            <UpdateForm onSubmit={onSubmit} encType="multipart/form-data">
                    {dropdownRessort.length > 0 && <DataHolder>
                    {dropdownRessort.map((item)=>(
                    <div key={item._id}>
                        <Label htmlFor="name">Name</Label>
                        <Input type="text" name="name" id="name" value={item.name} onChange={(e)=>updateData({name: e.target.value})}/>
                        <Label htmlFor="lis">MenüPunkte</Label>
                        <Input type="text" name="lis" id=""lis value={item.lis.join(", ")} onChange={(e)=>updateData({lis: e.target.value})}/>
                        <VideoWrapper>
                            <VideoSection>
                            <Label htmlFor="ressortvideo_1_iframe">Video 1 update</Label>
                            <Input type="text" name="ressortvideo_1_iframe" id="iframe" value={item.videos[0].iframe} onChange={(e)=>updateData({iframe: e.target.value})}/>
                            <Label htmlFor="ressort">Ressort</Label>
                            <Input type="text" name="ressort" id="ressort" value={item.videos[0].ressort} onChange={(e)=>updateData({ressort: e.target.value})}/>
                            <Label htmlFor="theme">Thema</Label>
                            <Input type="text" name="theme" id="theme" value={item.videos[0].theme} onChange={(e)=>updateData({theme: e.target.value})}/>
                            <Label htmlFor="title">title</Label>
                            <Input type="text" name="title" id="title" value={item.videos[0].title} onChange={(e)=>updateData({title: e.target.value})}/>
                        </VideoSection>
                        <VideoSection>
                            <Label htmlFor="ressortvideo_2_iframe">Video 2 update</Label>
                            <Input type="text" name="ressortvideo_2_iframe" id="iframe" value={data.videos[1].iframe} onChange={(e)=>updateData({iframe: e.target.value})}></Input>
                            <Label htmlFor="ressort">Ressort</Label>
                            <Input type="text" name="ressort" id="ressort" value={item.videos[1].ressort} onChange={(e)=>updateData({ressort: e.target.value})}/>
                            <Label htmlFor="theme">Thema</Label>
                            <Input type="text" name="theme" id="theme" value={item.videos[1].theme} onChange={(e)=>updateData({theme: e.target.value})}/>
                            <Label htmlFor="title">title</Label>
                            <Input type="text" name="title" id="title" value={item.videos[1].title} onChange={(e)=>updateData({title: e.target.value})}/>
                        </VideoSection>
                        <VideoSection>
                            <Label htmlFor="ressortvideo_3_iframe">Video 3 update</Label>
                            <Input type="text" name="ressortvideo_3_iframe" id="iframe" value={item.videos[2].iframe} onChange={(e)=>updateData({iframe: e.target.value})}></Input>
                            <Label htmlFor="ressort">Ressort</Label>
                            <Input type="text" name="ressort" id="ressort" value={item.videos[2].ressort} onChange={(e)=>updateData({ressort: e.target.value})}/>
                            <Label htmlFor="theme">Thema</Label>
                            <Input type="text" name="theme" id="theme" value={item.videos[2].theme} onChange={(e)=>updateData({theme: e.target.value})}/>
                            <Label htmlFor="title">title</Label>
                            <Input type="text" name="title" id="title" value={item.videos[2].title} onChange={(e)=>updateData({title: e.target.value})}/>
                        </VideoSection>
                        </VideoWrapper>
                        <Label htmlFor="themen">Themen</Label>
                            <Input type="text" name="themen" id="themen" value={item.themen} onChange={(e)=>updateData({themen: e.target.value})}/>
                        <ButtonHolder>
                            <UpdateButton type="submit">Update</UpdateButton>
                        </ButtonHolder>
                    </div>
                ))}
                    </DataHolder>  
                }  
            </UpdateForm>
        </ContentHolder>
        <Footer/>
    </Container>
  )
}

export default DropdownRessortEdit

CodePudding user response:

Try to remove dispatch from the dependencies in useEffect hook.

Because you want to fetch dispatch only when the component mount, not each time dispatch is changed.

So, in your code case, it will change dispatch which will re-trigger the hook which will fetch dispatch again which will change dispatch causes the hook to re-trigger and so on .. causing Infinity Loop.

CodePudding user response:

You can try to put dispatch in a React.useCallback function as shown in this example w3school React.useCallback

  • Related