Solo he estado jugando con ReactJs y ASP.net core y me pregunto por qué arroja un error de que cada componente debe tener una clave y cuando modifiqué mi código para asignar una clave, sigue mostrando el mismo mensaje. ¿Cómo podría resolverlo? ?
react.development.js:401 Advertencia: cada elemento secundario de una lista debe tener un accesorio de "clave" exclusivo.
Compruebe el método de renderizado de CommentBox . Ver https://fb. me/react-warning-keys para obtener más información. en etiqueta (creada por CommentBox) en CommentBox
class CommentBox extends React.Component { render() { const span = React.createElement('span', { className: "span" }, 'First Component React'); const label = React.createElement('label', { className: "label" }, span); const brTag = React.createElement('br') const textBox = React.createElement('input', { className: "input", placeholder: "Hola" }); const upperDiv = React.createElement('div', { key:"upperDivinput", className: "div" }, [label, brTag, textBox]); let comments = []; let baseUrl = 'https://localhost:44379'; let endPointComments = '/Posts/GetComments'; baseUrl = baseUrl + endPointComments; fetch(baseUrl) .then(response => response.json()) .then(result => { comments = result; console.log(result); }); let commentsParagraph = []; for (let i = 0; i < comments.length; i++) { console.log(comments[i].author); const paragItemTitle = React.createElement('p', { key:'author_${i}' ,className: "p" }, comments[i].author); const paragraphItemText = React.createElement('p', { key: 'comment_${i}', className: "p" }, comments[i].text); commentsParagraph.push(paragItemTitle); commentsParagraph.push(paragraphItemText); } const lowerDiv = React.createElement('div', { key:"lowerDivComments", className: 'div' }, commentsParagraph); const wrapperOuter = React.createElement('div', { key:"wapperDivComments", className:"div" }, [upperDiv, lowerDiv]) return wrapperOuter; } } ReactDOM.render(<CommentBox />, document.getElementById('root'));Sí, debe usar componentes funcionales en lugar de componentes de clase . componentWillMount() puede ser reemplazado por el gancho useEffect() . Y debería considerar usar JSX , ya que es mucho más fácil de leer que sus largas llamadas a createElement() . Probablemente sea mejor que comiences con la guía oficial de React .
Como mencioné en mi comentario, use ` (= comillas invertidas) para literales de cadena. Y trate de evitar el uso de un índice como clave, ya que un índice no es estable.
Aquí hay un pequeño ejemplo de un componente similar al que desea construir que usa literales de cadena, una buena clave, un componente funcional y una solicitud de API para solicitar algunos datos. Haga clic en este enlace para ver los datos ficticios que devuelve la API.
function CommentBox() { const [comments, setComments] = React.useState([]); React.useEffect(() => { const url = "https://gorest.co.in/public/v2/comments"; const response = fetch(url).then(resp => resp.json().then(json => setComments(json))); }, []); return ( <ul> {comments.map((comment) => ( <li> <span>{`Comment No. ${comment.id} from ${comment.name}`}</span> <blockquote>{comment.body}</blockquote> </li> ))} </ul> ); } ReactDOM.render(<CommentBox />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div> Desafortunadamente, no puedo usar async/await cuando uso React en StackOverflow, ya que tengo que marcar Babel/ ES2015 dentro de mi fragmento. Por lo general, usaría una función async en useEffect() y usaría await en lugar de encadenar then() .
El gancho useEffect() se vería así. Sin embargo, ambas versiones dan como resultado el mismo resultado.
React.useEffect(async () => { const url = "https://gorest.co.in/public/v2/comments"; const response = await fetch(url); const data = await resp.json(); setComments(data); }, []);Tenga en cuenta: aún necesitaría implementar algún manejo de errores aquí.
El problema está oculto con este tipo de código: [label, brTag, textBox] y [upperDiv, lowerDiv] .
Cada vez que tenga una matriz de elementos, cada elemento de esa matriz debe tener una clave. En este caso, su etiqueta, brTag y textBox necesitan una clave.
Además, nunca querrá hacer cosas como solicitudes de API dentro de su función de renderizado. Utilice los ganchos del ciclo de vida como componentDidMount para cargar datos y llamar a setState para activar un nuevo renderizado. NO llame a setState dentro de su método de renderizado.
Además, hágase un favor a usted mismo y a todos los demás y use JSX. Está compilado en tiempo de compilación (no en tiempo de ejecución), por lo que no le cuesta ningún rendimiento y es mucho más fácil de leer (nota: este consejo proviene de alguien que inicialmente se resistió a JSX). En tal caso, podría usar fragmentos de reacción y evitar tener que definir claves innecesarias:
<> <label>...</label> <br /> <input ... /> </>