0
votes

Appel d'API dans la méthode de rendu dans React à l'intérieur de la carte

J'ai un tableau userId et je dois afficher la liste des noms liés à ce tableau. Je souhaite appeler l'API dans la méthode render et obtenir le nom d'utilisateur. Mais ça ne fonctionne pas. Comment puis-je résoudre ce problème?

Voici ma méthode render :

renderName = (userId) => {
    axios.get(backendURI.url + '/users/getUserName/' + userId)
         .then(res => <div>{res.data.name}</div>)
}

Voici la fonction renderName :

render(){
    ...
    return(
        <div>
            {this.state.users.map(userId => {
                return (
                    <div> {this.renderName(userId )} </div>
                )
            })}
        </div>
    )
    ...
}


7 commentaires

avez-vous essayé de revenir pour l'appel api?


Vous devez renvoyer axios.get


J'ai renvoyé une chaîne codée en dur. Mais cela n'a pas fonctionné non plus. L'appel API fonctionne correctement


Vous ne pouvez pas définir jsx sur une promesse


utilisez async / await


@shayanmalinda axios.get est une promesse, vous ne pouvez pas le rendre. Cette approche n'est pas une très bonne pratique pour React, elle effectuera les appels d'API à chaque fois qu'elle sera restituée. Vous feriez mieux de faire les appels d'API lors du montage du composant, de stocker les résultats dans l'état, puis de rendre cet état. Et montrez simplement un indicateur de chargement pendant la récupération.


N'oubliez pas qu'un composant React peut être renvoyé plusieurs fois sans que vous ne vous en rendiez compte. Le rendu n'est pas toujours le même que la modification du DOM. Render est censé rendre l'interface utilisateur uniquement, sans effets secondaires (sauf peut-être console.log à des fins de débogage).


5 Réponses :


1
votes

En règle générale, vous ne modifiez pas l'état et ne récupérez pas les données directement dans la méthode de rendu. L'état est toujours modifié par des actions / événements (clics, entrée ou autre). La méthode render est appelée à chaque fois qu'un accessoire / état change. Si vous modifiez directement l'état dans la méthode de rendu, vous finissez par avoir une boucle infinie.

Vous devez utiliser les méthodes de cycle de vie ou les hooks pour charger des données à partir d'une API. Voici un exemple de la FAQ officielle React: https://reactjs.org/docs/faq-ajax .html


0 commentaires

1
votes

En gros, vous ne pouvez pas utiliser d'appels asynchrones dans un rendu car ils renvoient une Promise qui n'est pas JSX valide. Utilisez plutôt componentDidMount et setState pour mettre à jour le tableau des utilisateurs avec leurs noms.


0 commentaires

0
votes

Cela ne rendra rien car les appels d'API sont asynchrones et comme la fonction renderName ne renvoie rien, elle retournera undefined.

Vous devez créer une fonction, qui appellera api pour tous les userIds et mise à jour dans l'état

<div>
  {this.state.names.map((name) => {
    return <div> {name} </div>;
  })}
</div>

Vous pouvez maintenant appeler cette fonction dans componentDidMount ou componentDidUpdate , à tout moment Les données des utilisateurs sont disponibles.

Enfin, vous pouvez parcourir directement les noms et les rendre

getNames = () => {
    const promises = [];
    this.state.users.forEach((userId) => {
        promises.push(axios.get(backendURI.url+'/users/getUserName/'+userId));
    })

    // Once all promises are resolved, update the state
    Promise.all(promises).then((responses) => {
        const names = responses.map((response) => response.data.names);
        this.setState({names});
    })

}


0 commentaires

0
votes

Vous pouvez faire du nom d'utilisateur son propre composant:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>


<div id="root"></div>
const request = (id) =>
  new Promise((resolve) =>
    setTimeout(resolve(`id is:${id}`), 2000)
  );
const UserName = React.memo(function User({ userId }) {
  const [name, setName] = React.useState('');
  React.useEffect(() => {
    //make the request and set local state to the result
    request(userId).then((result) => setName(result));
  }, [userId]);
  return <div> {name} </div>;
});
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [1, 2],
    };
  }
  render() {
    return (
      <ul>
        {this.state.users.map((userId) => (
          <UserName key={userId} userId={userId} />
        ))}
      </ul>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));


0 commentaires

0
votes
export default ()=> {
  let [users,setUsers] = useState([]);

  useEffect(()=>{
    let fetchUsersInfoRemote = Promise.all([...Array(10)].map(async (_,index)=>{
        try {
          let response = await axios.get(`https://jsonplaceholder.typicode.com/posts/${index+1}`);
          return response.data;
        }
        catch(error) {
          return ;
        }
    }));

    fetchUsersInfoRemote.then(data=> setUsers(data));
  },[]);

  return (
    <div className="App">
      <ul>
        {
          users.map(user=>(<li><pre>{JSON.stringify(user,null,2)}</pre></li>))
        }
      </ul>
    </div>
  );
}

0 commentaires