Ik volg de reactjs
-tutorial en ik loop steeds tegen een probleem aan wanneer
de waarde van de staat van het ene onderdeel doorgeeft aan een ander onderdeel.
De fout Cannot read property 'map' of undefined'
wordt gegenereerd wanneer de functie map
in de component CommentList
wordt uitgevoerd.
Waarom zou de
prop
undefined
zijn bij het overgaan vanCommentBox
naar deCommentList
?
// First component
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment){
return <div><h1>{comment.author}</h1></div>;
});
return <div className="commentList">{commentNodes}</div>;
}
});
// Second component
var CommentBox = React.createClass({
getInitialState: function(){
return {data: []};
},
getComments: function(){
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data){ this.setState({data: data}) }.bind(this),
error: function(xhr, status, err){ console.error(url, status, err.toString()) }.bind(this)
});
},
componentWillMount: function(){
this.getComments()
},
render: function(){
return <div className="commentBox">{<CommentList data={this.state.data.comments}/>}</div>;
}
});
React.renderComponent( <CommentBox url="comments.json" />, document.getElementById('content'));
Antwoord 1, autoriteit 100%
Stel eerst meer veilige initiële gegevens in:
getInitialState : function() {
return {data: {comments:[]}};
},
En zorg voor uw ajax-gegevens.
Het zou moeten werken als je bovenstaande twee instructies volgt, zoals Demo.
Bijgewerkt: je kunt het .map-blok gewoon inpakken met een voorwaardelijke instructie.
if (this.props.data) {
var commentNodes = this.props.data.map(function (comment){
return (
<div>
<h1>{comment.author}</h1>
</div>
);
});
}
Antwoord 2, autoriteit 22%
Volgens mij bent u vergeten te wijzigen
data={this.props.data}
naar
data={this.state.data}
in de renderfunctie van CommentBox. Ik maakte dezelfde fout toen ik de tutorial volgde. Dus de hele renderfunctie zou er als volgt uit moeten zien
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
in plaats van
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
<CommentForm />
</div>
);
Antwoord 3, autoriteit 17%
U moet de gegevens voor het renderen plaatsen
Zou zo moeten zijn:
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
React.render(
<CommentBox data={data}/>,
document.getElementById('content')
);
In plaats van dit:
React.render(
<CommentBox data={data}/>,
document.getElementById('content')
);
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
Antwoord 4, autoriteit 10%
De fout "Cannot read property 'map' of undefined"
zal optreden als er een fout is in de "this.props.data"
of als er geen rekwisieten.data-array.
Beter voorwaarde om de array te controleren, zoals
if(this.props.data){
this.props.data.map(........)
.....
}
Antwoord 5, autoriteit 6%
Ik heb overwogen een reactie te geven onder het antwoord door taggon op deze vraag, maar goed, ik vond dat er meer aan de hand was uitleg voor diegenen die geïnteresseerd zijn in details.
Uncaught TypeError: kan eigenschap ‘waarde’ van undefined niet lezen is strikt een JavaScript-fout.
(Merk op dat waarde van alles kan zijn, maar voor deze vraag is waarde ‘kaart’)
Het is van cruciaal belang om dat punt te begrijpen, zodat u eindeloze foutopsporingscycli vermijdt.
Deze fout komt vaak voor, vooral als je net begint in JavaScript (en het zijn bibliotheken/frameworks).
Voor React
heeft dit veel te maken met het begrijpen van de methodes voor de levenscyclus van componenten.
// Follow this example to get the context
// Ignore any complexity, focus on how 'props' are passed down to children
import React, { useEffect } from 'react'
// Main component
const ShowList = () => {
// Similar to componentDidMount and componentDidUpdate
useEffect(() => {// dispatch call to fetch items, populate the redux-store})
return <div><MyItems items={movies} /></div>
}
// other component
const MyItems = props =>
<ul>
{props.items.map((item, i) => <li key={i}>item</li>)}
</ul>
/**
The above code should work fine, except for one problem.
When compiling <ShowList/>,
React-DOM renders <MyItems> before useEffect (or componentDid...) is called.
And since `items={movies}`, 'props.items' is 'undefined' at that point.
Thus the error message 'Cannot read property map of undefined'
*/
Als een manier om dit probleem aan te pakken, gaf @taggon een oplossing (zie eerste antwoord of link).
Oplossing: stel een begin-/standaardwaarde in.
In ons voorbeeld kunnen we voorkomen datitems
‘niet gedefinieerd’ zijn door eendefault
waarde van een lege array.Waarom? Hierdoor kan React-DOM in eerste instantie een lege lijst weergeven.
En wanneer de methodeuseEffect
ofcomponentDid...
is uitgevoerd, wordt de component opnieuw weergegeven met een ingevulde lijst met items.
// Let's update our 'other' component
// destructure the `items` and initialize it as an array
const MyItems = ({items = []}) =>
<ul>
{items.map((item, i) => <li key={i}>item</li>)}
</ul>
Antwoord 6, autoriteit 2%
De fout treedt voornamelijk op omdat de array niet wordt gevonden. Controleer gewoon of u bent toegewezen aan de juiste array. Controleer de arraynaam of declaratie.
Antwoord 7
in mijn geval gebeurt het wanneer ik probeer typen toe te voegen aan de Promise.all-handler:
Promise.all([1,2]).then(([num1, num2]: [number, number])=> console.log('res', num1));
Als u : [number, number]
verwijdert, is de fout verdwenen.
Antwoord 8
Dit werkte voor mij. als ik props.worktyp.map gebruik, krijg ik een foutmelding dat de kaart niet is gedefinieerd.
//App.js
const worktyp = [
"Full-time",
"casual",
"part-time",
"contract"
];
function Main(props){
return(
<section>
<p>This the main body</p>
<ul style = {{textAlign:"left"}}>
**{worktyp.map((work) => <li>{work}</li>)}**
</ul>
</section>
);
}
function App() {
return (
<div className="App">
<Header name="initial"/>
**<Main work={worktyp}/>**
<Foot year ={new Date().getFullYear()}/>
</div>
);
}
//index.js
ReactDOM.render(
<App />,
document.getElementById('root')
);