Javascript 在ReactJS中使用单独的方法填充渲染方法
好的,大家都知道单独的映射可以在React render方法中渲染组件,如下所示:Javascript 在ReactJS中使用单独的方法填充渲染方法,javascript,reactjs,firebase,google-cloud-firestore,Javascript,Reactjs,Firebase,Google Cloud Firestore,好的,大家都知道单独的映射可以在React render方法中渲染组件,如下所示: var listOfService = ['A', 'B', 'C', 'D', 'E']; const listItems = listOfService.map((singleItem) => <a className="style_class">{singleItem}</a> ); 所以我尝试了这个方法,但不起作用,我写了一些控制台日志,数据输入正确。首先,我得到整
var listOfService = ['A', 'B', 'C', 'D', 'E'];
const listItems = listOfService.map((singleItem) =>
<a className="style_class">{singleItem}</a>
);
所以我尝试了这个方法,但不起作用,我写了一些控制台日志,数据输入正确。首先,我得到整个“
提供者
”文档数组,提供者列表作为“快照
”传递,因此我使用另一个函数循环通过快照,该函数获取一个名为文档
的文档,然后将其推入名为详细信息
的变量中,这是一个数组数组,但是!它不工作,数组没有被填充,即使数据在那里,因此我无法映射,关于如何实现这一点有什么想法吗?您需要分离数据加载和数据呈现,因为检索数据是异步的,呈现需要是同步的
例如,在您的情况下,您正在将详细信息推入然后
回调中的数组-这将对主函数发生async
,因此当您调用details.map
时,它仍然是空的(回调没有启动来填充它)
相反,您可以加载数据并将其存储在状态中,然后在数据可用时进行渲染。就我个人而言,我更喜欢async/await
,但在承诺上使用then
也可以实现同样的逻辑:
const [details, setDetails] = useState([]);
// Load the data on initial load or setup the effect to fire when reload is needed
useEffect(() => {
// Async function that loads the data and sets the state once ready
const loadData = async () => {
const details = [];
try {
const snapshot = await db.collection('providers').get();
snapshot.forEach((doc) => {
details.push([
// your details stuff
]);
}
} catch (ex) {
// Handle any loading exceptions
}
setDetails(details);
}
}, [])
// Render the available details, you could also add conditional rendering to check
// if the details are available or not yet
return (
<div>
{details.map((singleDetail) => (
<Service details={singleDetail} />
)};
</div>
);
const[details,setDetails]=useState([]);
//在初始加载时加载数据,或设置在需要重新加载时触发的效果
useffect(()=>{
//异步函数,用于加载数据并设置就绪后的状态
const loadData=async()=>{
常量详细信息=[];
试一试{
const snapshot=await db.collection('providers').get();
snapshot.forEach((doc)=>{
推送([
//你的细节资料
]);
}
}捕获(ex){
//处理任何加载异常
}
设置详细信息(详细信息);
}
}, [])
//渲染可用的详细信息时,还可以添加条件渲染以进行检查
//是否有详细信息
返回(
{details.map((singleDetail)=>(
)};
);
如果您使用的是React类而不是功能组件,则可以从componentDidMount
调用加载,并在加载后仍然设置状态,然后在渲染时映射状态数据。我使用ReactDOM.render方法找到了解决方案
首先创建一个全局数组:
var Services = [];
然后添加一个可以放置和渲染数组的DOM元素:
<div className="row d-flex justify-content-center" id='service-div'>
</div>
现在在这个方法中,只需填充数组,然后使用ReactDOM.render方法将其渲染到给定的DOM元素
async renderServices() {
let history = this.props.history; //in case the method can't access the history
let db = firebase.firestore();
selectedServices = this.props.location.state.selectedServices;
var database = firebase.database();
db.collection('providers').where('services', 'array-contains-any',
selectedServices).get()
.then(function (snapshot) {
let idCount = 0;
snapshot.forEach(function (doc) {
let tempDetails = [];
tempDetails.push(
doc.data().owner_name,
doc.data().experience,
doc.data().charges,
doc.data().address,
doc.data().home_service,
doc.data().highlights,
doc.data().certifications,
doc.data().specialty,
doc.data().facility,
doc.data().services,
doc.data().call_extension,
idCount.toString()
);
Services.push(<Service details={tempDetails} history={history} />); //adding the Service Component into a list
idCount++;
});
ReactDOM.render(<div>{Services}</div>, document.getElementById('service-div')); //now rendering the entire list into the div
}).catch(function (error) {
console.log(error);
});
}
async renderServices(){
让history=this.props.history;//如果方法无法访问历史记录
设db=firebase.firestore();
selectedServices=this.props.location.state.selectedServices;
var database=firebase.database();
db.collection('providers')。其中('services','array包含any',
selectedServices.get()
.then(功能(快照){
设idCount=0;
snapshot.forEach(函数(文档){
设tempDetails=[];
临时推送(
文档数据()所有者名称,
文档数据()经验,
单据数据()费用,
doc.data().地址,
doc.data().home_服务,
doc.data()突出显示,
文档数据()证书,
doc.data().speciality,
doc.data().facility,
doc.data()服务,
doc.data().调用扩展名,
idCount.toString()
);
Services.push();//将服务组件添加到列表中
idCount++;
});
ReactDOM.render({Services},document.getElementById('service-div'));//现在将整个列表呈现到div中
}).catch(函数(错误){
console.log(错误);
});
}
你说的“我知道你不能在循环或if语句中使用JSX”是什么意思?你已经从循环中返回了JSX,所以你确定这就是你的意思吗?我对firestore没有太多经验,但这样的操作通常是异步的(基于你对的使用,那么
我会说就是这样)。当你试图偶然地做映射时,details
仍然是一个空数组吗?@Brianthonpson yea细节数组保持为空,它的werid。我在details.push()前面写了console.log行它显示了所有数据,但似乎无法将相同的数据传递给细节数组。这就像某种阻塞和超出范围的问题创建jsx元素数组,即代码中的服务组件。将文档作为细节传递给服务,并从函数返回细节数组。好的,我做了类似的事情,它似乎加载了所有数据但是它并不像你在代码中写的那样映射,让我看看这是怎么回事
ComponentDidMount(){
this.renderServices();}
async renderServices() {
let history = this.props.history; //in case the method can't access the history
let db = firebase.firestore();
selectedServices = this.props.location.state.selectedServices;
var database = firebase.database();
db.collection('providers').where('services', 'array-contains-any',
selectedServices).get()
.then(function (snapshot) {
let idCount = 0;
snapshot.forEach(function (doc) {
let tempDetails = [];
tempDetails.push(
doc.data().owner_name,
doc.data().experience,
doc.data().charges,
doc.data().address,
doc.data().home_service,
doc.data().highlights,
doc.data().certifications,
doc.data().specialty,
doc.data().facility,
doc.data().services,
doc.data().call_extension,
idCount.toString()
);
Services.push(<Service details={tempDetails} history={history} />); //adding the Service Component into a list
idCount++;
});
ReactDOM.render(<div>{Services}</div>, document.getElementById('service-div')); //now rendering the entire list into the div
}).catch(function (error) {
console.log(error);
});
}