我正在学习反应,希望尝试创建一个显示加载文本的加载组件,直到满足条件(即道具具有正确的信息)为止。
问题是即使不满足条件,元素仍在加载:
主要组成部分:
import React from 'react';
const Loading = ({ condition, children }) => (<div>{condition ? children :
'Loading'}</div>);
export default Loading;
这是我使用加载组件的组件的渲染方法:
return
(<Loading condition={props.data && props.data.result && props.data.result.length > 1}>
<div> { ViewHelper.getCatalogItems(props.data) }</div></Loading>);
现在我的问题是,由于未定义props.data,所以在调用{ ViewHelper.getCatalogItems(props.data) }
时出现错误,但是我希望如果LoadingComponent中的三元条件为false,则Loading Component不会调用该函数。
如果我将ViewHelper.getData更改为仅某个字符串值,则一切似乎正常,并且显示“正在加载”。
谢谢
答案 0 :(得分:1)
更新后的答案:如以下发情期所述,渲染道具可能是实现此目的的好方法。这是一个示例:
import React from "react";
import ReactDOM from "react-dom";
const Loading = ({ condition, render }) => {
if (condition) {
return render();
} else {
return "Loading";
}
};
const Thing = ({ data }) => {
console.log(data);
return data.map(d => <li>{d}</li>);
};
class App extends React.Component {
state = {
data: [1, 2, 3]
};
render() {
return (
<Loading
condition={this.state.data.length > 1}
render={() => {
return <Thing data={this.state.data} />;
}}
/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
CodeSandbox here。
答案 1 :(得分:1)
需要在此处处理props.data的情况。有多种方法可以做到这一点:
答案 2 :(得分:1)
Loading
组件未使用children
的事实并不意味着未渲染子级。否则,没有任何内容可以作为props.children
传递给父组件。
从this example中可以看出,尽管在父组件中忽略了children
道具,但仍对子表达式进行了评估。
处理此问题并防止儿童急于渲染的正确方法是使用render prop食谱,也称为function as a child:
const Loading = ({ condition, children }) => (
<div>{condition && children ? children() : 'Loading'}</div>
);
...
<Loading condition={props.data && props.data.result && props.data.result.length > 1}>
{() => (
<div> { ViewHelper.getCatalogItems(props.data) }</div>
)}
</Loading>
请注意,由于props.children
是一个函数,因此在三元表达式中将其用作children()
。
或将HOC用于组件:
const withLoading = (Comp) =>
({ condition, ...props }) => (
<div>{condition ? <Comp {...props} /> : 'Loading'}</div>
)
);
...
const LoadingCatalogItemsComponent = withLoading(CatalogItemsComponent);
答案 3 :(得分:1)
与@estus said一样,HOC和渲染道具是两种流行的方法。正在移动:
<div>{ ViewHelper.getCatalogItems(props.data)}</div>
进入自己的组件(通过道具,例如<CatalogItems {...props} />
)也会阻止您出错。只要代码不在实际的render方法中;否则,无论React是否会实际渲染它,它都会被触发。
示例:
const Loading = ({ condition, children }) => (
<div>{condition ? children : "Loading in 3 seconds"}</div>
);
// now that it's in its own component the code isn't run until the component actually renders
const CatalogItems = ({ data }) => data.result.map(item => item);
class App extends React.Component {
state = {
data: null
};
// dummy API call
componentDidMount() {
setTimeout(
() => this.setState({ data: { result: ["cat ", "dog ", "mouse "] } }),
3000
);
}
render() {
const props = this.state; // let's just pretend these were inherited props
return (
<Loading
condition={
props.data && props.data.result && props.data.result.length > 1
}
data={props.data}
>
<CatalogItems {...props} />
</Loading>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<div id='root'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.1/umd/react-dom.development.js"></script>