无法访问状态对象(React useState hook)



我试图访问一个状态对象,它有一个名为allMemes的属性。

获取json数据后,返回一个包含100个元素的数组。

另一个属性是使用这个数组从长度中获得一个随机数。到目前为止,我一直得到错误"TypeError: Cannot read properties of undefined (reading 'url')"

我想了解这个错误,并对我的代码有一些反馈。谢谢!

const Memes = () => {
const INITIAL_STATE = {
topText: '',
bottomText: '',
randomImg:'https://i.imgflip.com/26am.jpg',
allMemes: [],
};


useEffect(() => {
fetchMemes()
}, []);

const fetchMemes = () => {

console.log('loading memes data');
try {
fetch('https://api.imgflip.com/get_memes')
.then(response => response.json())
.then(response => {
const memesArray = response.data.memes;
console.log('memeArray', memesArray);
setInputs(inputs =>({...inputs, allMemes: {...inputs.allMemes.memesArray}}));
// console.log('inputs', inputs);    
});        
} catch (error) {
console.log(error)
}       
}

const handleChange = (e) => {
const {name, value} = e.target;
setInputs(inputs => ({...inputs, [name]: value}))    
};
const handleSubmit = (e) => {
e.preventDefault();
const randNum = Math.floor(Math.random() * inputs.allMemes.length);
setInputs(inputs =>({...inputs, randomImg: inputs.allMemes[randNum].url}));
// console.log('randomimg', inputs.randomImg);
// console.log('memes', inputs.allMemes);
};
const [inputs, setInputs] = useState(INITIAL_STATE);

return (
<>
<form onSubmit={handleSubmit}>
<label htmlFor="top">Top Text:</label>
<input type="text" name="topText" id="top" value={inputs.topText} onChange={handleChange}></input>
<label htmlFor="btm">Bottom Text:</label>
<input type="text" name="bottomText" id="btm" value={inputs.bottomText} onChange={handleChange}></input>
<button>Generate</button>  
</form>
<div>
<h3>{inputs.topText}</h3>
<h3>{inputs.bottomText}</h3>
<h3>{inputs.randomImg}</h3>
<image src={inputs.randomImg} alt='' />
</div>

</>
)
}
export default Memes;

fetchMemes()方法中,您正在设置

  1. 错误的数据类型:(将数组赋值为对象)

setInputs(inputs =>({...inputs, allMemes: {...inputs.allMemes.memesArray}}));
------------------------------------------^ 

你应该设置array而不是object []/{}

    • 你没有传递获取的数据,所以你总是得到未定义的数组:

...memesArray代替...inputs.allMemes.memesArray

也将image改为img标签

见下面的工作片段

// Get a hook function
const {
useState,
useEffect
} = React;
const Memes = () => {
const INITIAL_STATE = {
topText: '',
bottomText: '',
randomImg: 'https://i.imgflip.com/26am.jpg',
allMemes: [],
};

useEffect(() => {
fetchMemes()
}, []);
const fetchMemes = () => {
console.log('loading memes data');
try {
fetch('https://api.imgflip.com/get_memes')
.then(response => response.json())
.then(response => {
const memesArray = response.data.memes;
//console.log('memeArray', memesArray);
setInputs(inputs => ({ ...inputs,
allMemes: [ ...memesArray
]
}));
// console.log('inputs', inputs);    
});
} catch (error) {
console.log(error)
}
}
const handleChange = (e) => {
const {
name,
value
} = e.target;
setInputs(inputs => ({ ...inputs,
[name]: value
}))
};
const handleSubmit = (e) => {
e.preventDefault();

const randNum = Math.floor(Math.random() * inputs.allMemes.length);

setInputs(inputs => ({ ...inputs,
randomImg: inputs.allMemes[randNum].url
}));
// console.log('randomimg', inputs.randomImg);
// console.log('memes', inputs.allMemes);
};
const [inputs, setInputs] = useState(INITIAL_STATE);
return ( 
<React.Fragment>
<form onSubmit={handleSubmit}>
<label htmlFor="top">Top Text:</label>
<input type="text" name="topText" id="top" value={inputs.topText} onChange={handleChange}></input>
<label htmlFor="btm">Bottom Text:</label>
<input type="text" name="bottomText" id="btm" value={inputs.bottomText} onChange={handleChange}></input>
<button>Generate</button>  
</form>
<div>
<h3>{inputs.topText}</h3>
<h3>{inputs.bottomText}</h3>
<h3>{inputs.randomImg}</h3>
<img src={inputs.randomImg} height={120} alt='' />
</div>
</React.Fragment>   
);
};
// Render it
ReactDOM.render(<Memes />,document.getElementById("app"));
const Memes = () => {
const INITIAL_STATE = {
topText: '',
bottomText: '',
randomImg:'https://i.imgflip.com/26am.jpg',
allMemes: [],
};


useEffect(() => {
fetchMemes()
}, []);
const fetchMemes = () => {

console.log('loading memes data');
try {
fetch('https://api.imgflip.com/get_memes')
.then(response => response.json())
.then(response => {
const memesArray = response.data.memes;
console.log('memeArray', memesArray);
setInputs(inputs =>({...inputs, allMemes: {...inputs.allMemes.memesArray}}));
// console.log('inputs', inputs);    
});        
} catch (error) {
console.log(error)
}       
}
const handleChange = (e) => {
const {name, value} = e.target;
setInputs(inputs => ({...inputs, [name]: value}))    
};
const handleSubmit = (e) => {
e.preventDefault();
const randNum = Math.floor(Math.random() * inputs.allMemes.length);
setInputs(inputs =>({...inputs, randomImg: inputs.allMemes[randNum].url}));
// console.log('randomimg', inputs.randomImg);
// console.log('memes', inputs.allMemes);
};
const [inputs, setInputs] = useState(INITIAL_STATE);

return (

)
<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="app"></div>

在fetchMemes函数中,当您设置输入时,

setInputs(inputs =>({...inputs, allMemes: [...inputs.allMemes.memesArray]}));

在设置allMemes时,应该对数组使用扩展操作符。但是,你正在使用一个对象。

最新更新