Javascript 即使正确传递子组件道具,也无法呈现它们
我被这件事缠住了,我不知道我做错了什么。我正在尝试使用Wikipedia查看器(如本文所述),基本上是对Wikipedia文章的简单搜索 我已经在HTML/CSS/JS(jQuery)中完成了这项工作,现在我正在学习React,我正在尝试在React中重新创建它 我已经分解了我的组件,我使用fetch来使用wikipediaapi获取数据,除了搜索结果之外,所有的东西都在呈现。我无法显示最终结果,这是整个“应用程序”的要点 使用React-Dev工具,我已经确定正在获取数据,并且正在将道具传递给子组件,并且我已经测试了一个虚拟子组件是否会呈现,它确实呈现了,所以呈现所有组件不是问题,我只是缺少一些步骤,无法让它呈现包含所有必要数据的组件 所有代码都在代码沙箱中。我已经按照我在本地设置的方式设置了它,这样你就可以清楚地看到我是如何做的 感谢您的帮助 抱歉,如果问题有点长,包含所有文本和代码。如果对某些人来说更方便的话,我还包括了按文件分割的所有代码 App.jsxJavascript 即使正确传递子组件道具,也无法呈现它们,javascript,reactjs,Javascript,Reactjs,我被这件事缠住了,我不知道我做错了什么。我正在尝试使用Wikipedia查看器(如本文所述),基本上是对Wikipedia文章的简单搜索 我已经在HTML/CSS/JS(jQuery)中完成了这项工作,现在我正在学习React,我正在尝试在React中重新创建它 我已经分解了我的组件,我使用fetch来使用wikipediaapi获取数据,除了搜索结果之外,所有的东西都在呈现。我无法显示最终结果,这是整个“应用程序”的要点 使用React-Dev工具,我已经确定正在获取数据,并且正在将道具传递给
从“React”导入React;
从“./Header”导入WikiHeader;
从“./Search”导入WikiSearch;
从“/OutputList”导入OutputList;
导入“purecss”;
导入“purecss/build/grids-responsive-min.css”
导入“/App.css”;
var结果数组=[];
常量wikiAPI=”https://en.wikipedia.org/w/api.php?&";
var wikiHeaders={
行动:“查询”,
格式:“json”,
来源:“*”,
道具:“信息|摘录”,
例句:2,
exlimit:5,
生成器:“搜索”,
inprop:“url”,
GSR研究:“,
gsrnamespace:0,
gsrlimit:5,
出口:1
};
//格式化要用于查询字符串的标题
函数toQueryString(obj){
var部分=[];
用于(obj中的var i){
if(对象为自有财产(i)){
push(encodeURIComponent(i)+“=”+encodeURIComponent(obj[i]));
}
}
返回零件。连接(“&”);
}
类应用程序扩展了React.Component{
构造函数(){
超级();
此.state={
结果:[]
}
this.ajaxCall=this.ajaxCall.bind(this);
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
//使用fetch的AJAX
ajaxCall(){
resultsArray=[];//每次调用ajax时清除数组,这样它就不会只向以前的项添加新项
toQueryString(wikiHeaders);
获取(wikiAPI+toQueryString(wikiHeaders))。然后(函数(响应){
返回response.json();
}).then(函数(json){
for(json.query.pages中的var prop){
//将响应项推送到数组中,这样状态就不会直接更改(Facebook建议不要更改状态)
结果数组推送({
标题:json.query.pages[prop]。标题,
url:json.query.pages[prop].fullurl,
摘录:json.query.pages[prop].extract
});
}
}).catch(函数(ex){
console.log('Json解析失败',ex);//如果Json解析失败,则显示错误
});
this.setState({results:resultsArray});//将state.results设置为resultsArray
}
手变(e){
wikiHeaders.gsrsearch=e.target.value;//获取输入值并存储它
}
handleSubmit(e){
e、 预防默认值();
log(“嘿,这是一个提交事件!”);//显示是否正在调用函数
//呼叫取回
这个.ajaxCall();
//提交后清除搜索框
document.getElementById(“搜索输入”).value=“”;
}
render(){
返回(
);
}
}
导出默认应用程序;
Header.jsx
从“React”导入React;
类WikiHeader扩展了React.Component{
render(){
返回(
维基百科查看器
);
}
};
导出默认WikiHeader;
Search.jsx
从“React”导入React;
类WikiSearch扩展了React.Component{
render(){
返回(
搜寻
);
}
};
导出默认维基搜索;
OutputList.jsx
从“React”导入React;
从“/OutputItem”导入OutputItem;
类OutputList扩展了React.Component{
render(){
var finalResult=this.props.results.map((结果,索引)=>{
返回(
);
});
返回(
{finalResult}
);
}
}
导出默认输出列表;
OutputItem.jsx
从“React”导入React;
类OutputItem扩展了React.Component{
render(){
返回(
);
}
}
导出默认输出项;
我想我已经在你的沙盒上成功了
this.setState({results:resultsArray})代码>在错误的时间完成。它必须等待AJAX调用完成。我把它放在你的后面
for(json.query.pages中的var prop){
循环,因此在ajax解析回调中
由此产生的问题是,this
不再引用组件实例,因此this.setState
变得未定义。为了避免该问题,我将)。然后(函数(json){
转换为箭头函数,这样它就不会覆盖this
你可以看到我更新的沙盒。如果我添加到你当前的应用程序并运行它,我可以观察到你的finalResults
变量是空的,即使查询有效。这是因为fetch
中的resultsArray
变量由于Javascript上下文的原因与外部变量不同
您可以首先在var=this;
中提升旧上下文,然后在需要执行另一个setState
时使用它
在App.jsx中,ajax调用和集合
import React from 'react';
import WikiHeader from './Header';
import WikiSearch from './Search';
import OutputList from './OutputList';
import 'purecss';
import 'purecss/build/grids-responsive-min.css'
import './App.css';
var resultsArray = [];
const wikiAPI = "https://en.wikipedia.org/w/api.php?&";
var wikiHeaders = {
action: "query",
format: "json",
origin: "*",
prop: "info|extracts",
exsentences: 2,
exlimit: 5,
generator: "search",
inprop: "url",
gsrsearch: "",
gsrnamespace: 0,
gsrlimit: 5,
exintro: 1
};
// Format headers to be used for a query string
function toQueryString(obj) {
var parts = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
}
}
return parts.join("&");
}
class App extends React.Component {
constructor() {
super();
this.state = {
results: []
}
this.ajaxCall = this.ajaxCall.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// AJAX using fetch
ajaxCall() {
resultsArray = []; // clear array every time ajax is called so that it doesn't just add new items to previous items
toQueryString(wikiHeaders);
fetch(wikiAPI + toQueryString(wikiHeaders)).then(function(response) {
return response.json();
}).then(function(json) {
for (var prop in json.query.pages) {
// push response items to array so that state isn't directly changed (not changing state recommended by Facebook)
resultsArray.push({
title: json.query.pages[prop].title,
url: json.query.pages[prop].fullurl,
extract: json.query.pages[prop].extract
});
}
}).catch(function(ex) {
console.log('Json parsing failed', ex); // show error if JSON parsing fails
});
this.setState({results: resultsArray}); // set state.results to resultsArray
}
handleChange(e) {
wikiHeaders.gsrsearch = e.target.value; // get input value and store it
}
handleSubmit(e) {
e.preventDefault();
console.log("Hey, this is a submit event!"); // show if function is being called
// Call fetch
this.ajaxCall();
// Clear the search box after submit
document.getElementById("search-input").value = "";
}
render() {
return (
<div className="full-wrapper pure-g">
<div className="pure-u-1">
<WikiHeader />
<WikiSearch onChange={this.handleChange} onSubmit={this.handleSubmit} />
<OutputList results={this.state.results} />
</div>
</div>
);
}
}
export default App;
import React from 'react';
class WikiHeader extends React.Component {
render() {
return (
<h1 className="site-title">Wikipedia Viewer</h1>
);
}
};
export default WikiHeader;
import React from 'react';
class WikiSearch extends React.Component {
render() {
return (
<div className="search-input">
<form className="pure-form" onSubmit={this.props.onSubmit}>
<div className="pure-u-1 pure-u-md-3-4">
<input type="text" id="search-input" onChange={this.props.onChange} className="pure-input pure-u-1" placeholder="Input your search term here..."></input>
</div>
<div className="pure-u-1 pure-u-md-1-4 button-wrapper">
<button type="submit" id="search-button" className="pure-button pure-button-primary pure-u-1 pure-u-md-23-24">Search</button>
</div>
</form>
<a href="https://en.wikipedia.org/wiki/Special:Random" alt="Open a Random Wikipedia article" target="_blank" rel="noopener noreferrer">or see a random Wikipedia article</a>
</div>
);
}
};
export default WikiSearch;
import React from 'react';
import OutputItem from './OutputItem';
class OutputList extends React.Component {
render() {
var finalResult = this.props.results.map((result, index) => {
return (
<OutputItem
key={index}
title={result.title}
url={result.url}
extract={result.extract}
/>
);
});
return (
<div id="search-output" className="pure-g">
<ul className="article-list pure-u-1">
{finalResult}
</ul>
</div>
);
}
}
export default OutputList;
import React from 'react';
class OutputItem extends React.Component {
render() {
return (
<div>
<li className="pure-u-1">
<a href={this.props.url} target="_blank" rel="noopener noreferrer">
<h2>{this.props.title}</h2>
{this.props.extract}
</a>
</li>
</div>
);
}
}
export default OutputItem;