带有钩子的 React 中的默认和延迟渲染值问题

Posted

技术标签:

【中文标题】带有钩子的 React 中的默认和延迟渲染值问题【英文标题】:Problems with default and delay rendering values in React with hooks 【发布时间】:2021-01-11 20:01:21 【问题描述】:

Stackover Flow 中的新反应和第一个问题

我有一个不明白的问题,我正在尝试在表单中显示默认值以更新成员。 我知道,我必须在输入中使用 defaultValue 并指出我从数据库中获得的值。我这样做是为了更新其他信息,但是对于我的成员(以及另一个集合)它不起作用。

第一个问题是我的 useEffect 出现错误:警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。 似乎可以用这个来解决:https://codesandbox.io/s/l458746w89?from-embed=&file=/src/AxiosHooksComponent.js

但 defaultValues 没有出现。最糟糕的是,当我将 data.nom 放入表单(在 Nom 旁边)时,什么都没有。

我试图延迟渲染,我收到一条消息,表明它正在加载,然后表单出现但没有我想要的数据。 我从我的后端控制台记录数据,我得到了它们,但没有在我的回报中。

我哪里错了?这是我的代码。如果您需要更多信息,请随时询问

import React,  useState, useEffect  from 'react';
import  useParams, useHistory, Link  from 'react-router-dom';

import ErrorNotice from '../misc/ErrorNotice';
import Requete from '../../middlewares/Requete';
import axios from 'axios';

export default function UpdateMembre()

const [nom, setNom]= useState();
const [prenom, setPrenom]= useState();
const [email, setEmail]= useState();
const [mot_de_passe, setMotDePasse]= useState();
const [mot_de_passe_confirmation, setMotDePasseConfirmation]= useState();
const [telephone, setTelephone]= useState();
// const [commune_entreprise, setCommuneEntreprise] = useState();
const [error, setError] = useState();
const [data, setData] = useState([]);

const history = useHistory();
const  id  = useParams();

let token = localStorage.getItem("auth-token");
if(token === null)
    localStorage.setItem('auth-token', "");
    token = "";


// useEffect(function()

//     async function fetchData()
//         const result = await Requete.get(
//             '/membres/afficher/' + id,
//              headers:  "x-auth-token": token  ,
//         );
//         setData(result);
//     ;
//     fetchData();
// );

useEffect(() => 

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();

    const fetchData = () => 
        try
            Requete.get(
                '/membres/afficher/' + id,
                 headers:  "x-auth-token": token , cancelToken: source.token,
            ).then(data => setData(data.data));
         catch(error)
            if(axios.isCancel(error)) 
                console.log("Cancelled");
             else 
                throw error;
            
        
    ;
    fetchData();
    return () => 
        source.cancel();
    ;
, [id, token])

const submit = async function(e)
    e.preventDefault();

    try
        const majMembre =  nom, prenom, email, mot_de_passe, mot_de_passe_confirmation, telephone ;
        await Requete.put(
            "/membres/maj/" + id,
            majMembre,
             headers:  "x-auth-token": token  ,
        );
        history.push("/membre/" + id);
     catch(err)
        err.response.data.msg && setError(err.response.data.msg); //Les 2 doivent être vrai pour être executés. Si le premier est vrai, le setState s'executera pour stocker le message d'erreur
    


return(
    console.log("data: ", data),
    <div>
        data.length === 0 ? (
            <p>Chargement des données</p>
        ) : (
        <div className="col-md-12">
            <div className="card card-container">
                <img
                    src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
                    
                    className="profile-img-card"
                />
                error && (
                    <ErrorNotice message=error clearError=()=> setError(undefined) />
                ) /*S'il y a une erreur, affiche le message d'erreur, la faction anonyme supprime quand on clique */
                <form onSubmit=submit>
                    <div className="form-group">
                    <label>Nom: data.nom</label>
                        <input
                            defaultValue=data.nom
                            type='text'
                            className='form-control'
                            placeholder='Votre nom'
                            onChange=(e) => setNom(e.target.value)
                        />
                    </div>
                    <div className="form-group">
                        <label>Prénom:</label>
                        <input
                            defaultValue=data.prenom
                            type='text'
                            className='form-control'
                            placeholder='Votre prénom'
                            onChange=(e) => setPrenom(e.target.value)
                        />
                    </div>
                    <div className="form-group">
                        <label>Email:</label>
                        <input
                            defaultValue=data.email
                            type='text'
                            className='form-control'
                            placeholder='Votre email'
                            onChange=(e) => setEmail(e.target.value)
                        />
                    </div>
                    <div className='form-group'>
                        <label>Mot de passe:</label>
                        <input
                            type='password'
                            className='form-control'
                            placeholder='Mot de passe'
                            onChange=(e) => setMotDePasse(e.target.value)
                        />
                    </div>
                    <div className='form-group'>
                        /* <label>Confirmation de votre mot de passe:</label> */
                        <input
                            type='password'
                            className='form-control'
                            placeholder='Confirmez votre mot de passe'
                            onChange=(e) => setMotDePasseConfirmation(e.target.value)
                        />
                    </div>
                    <div className='form-group'>
                        <label>Téléphone:</label>
                        <input
                            defaultValue=data.telephone
                            className='form-control'
                            type='tel'
                            pattern='[0-9]2[0-9]2[0-9]2[0-9]2[0-9]2'
                            placeholder='06 xx xx xx xx'
                            onChange=(e) => setTelephone(e.target.value)
                        />
                    </div>
                    /* <div className='form-group'>
                        <label>Dans quelle commune travaillez-vous ?</label>
                        <select 
                            className='form-control'
                            // value=this.state.commune
                            onChange=(e) => setCommuneEntreprise(e.target.value)               
                        >
                            <option>Aucune</option>
                            optionItems
                        </select>
                    </div> */
                    <div className='form-group'>
                        <input type='submit' value='Inscription' className='btn btn-primary'/>
                        <p><Link to="/membre/" + id>Retour</Link></p>
                    </div>
                </form>
            </div>
        </div>
        )
    </div>
)

【问题讨论】:

【参考方案1】:

我找到了我的问题的解决方案,我不知道为什么但是使用相同的请求格式,我的后端的响应与我的其他功能更新不同。

我必须输入 data[0].nom 来显示我的值

【讨论】:

以上是关于带有钩子的 React 中的默认和延迟渲染值问题的主要内容,如果未能解决你的问题,请参考以下文章

react中的生命周期钩子函数? 每个都是干什么用的?

React:useState 钩子中的 setState 在啥情况下会导致重新渲染?

初始渲染时未定义 useRef 值

如何使用 react-redux 钩子测试组件?

如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

React - 带有异步 setState 的 useEffect 导致额外的重新渲染