Javascript 将布尔状态传递给多个子对象
预期的 我想在tab的内容中设置一个加载状态,每当用户单击tab标题切换tab时,一个标志会传递给子项 问题 我有这个应用程序组件,我用setTimeout伪造它的api调用Javascript 将布尔状态传递给多个子对象,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,预期的 我想在tab的内容中设置一个加载状态,每当用户单击tab标题切换tab时,一个标志会传递给子项 问题 我有这个应用程序组件,我用setTimeout伪造它的api调用 class App extends Component { state = { loading: false, data: [] } getData = () => { return new Promise(resolve => { return se
class App extends Component {
state = {
loading: false,
data: []
}
getData = () => {
return new Promise(resolve => {
return setTimeout(() => {
resolve(
[
{
id: 1,
name: "Kelas A",
list: ["Jane", "Ali", "Ahmad"]
},
{
id: 2,
name: "Kelas B",
list: ["May", "Henry", "Ben"]
}
]
)
},500)
})
}
async componentDidMount() {
this.setState({
loading: true
})
const data = await this.getData()
this.setState({
data,
loading: false
})
}
//loadingComponent = () => <div>Loading...</div>;
render() {
const { data, loading } = this.state
return (
<Tabs
activeTab={1}
loading={loading}
//loadingComponent={this.loadingComponent()}
>
{data.map(o => (
<Tab
id={o.id}
>
<Tab.Title>{o.name}</Tab.Title>
<Tab.Content>
{o.list.join(", ")}
</Tab.Content>
</Tab>
))}
</Tabs>
);
}
}
类应用程序扩展组件{
状态={
加载:false,
数据:[]
}
getData=()=>{
返回新承诺(解决=>{
返回setTimeout(()=>{
决心(
[
{
id:1,
名称:“科拉斯A”,
名单:[“简”、“阿里”、“艾哈迈德”]
},
{
id:2,
名称:“卡拉斯B”,
名单:[“五月”、“亨利”、“本”]
}
]
)
},500)
})
}
异步组件didmount(){
这是我的国家({
加载:正确
})
const data=wait this.getData()
这是我的国家({
数据,
加载:错误
})
}
//加载组件=()=>加载。。。;
render(){
const{data,loading}=this.state
返回(
{data.map(o=>(
{o.name}
{o.list.join(“,”)}
))}
);
}
}
我将加载状态作为道具传递给Tabs子组件,它成功了,我可以看到正确和错误:
class Tabs extends Component {
static defaultProps = {
activeTab: 1
};
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.loading !== prevState.loading){
return {
loading: nextProps.loading
}
}
}
state = {
activeTab: this.props.activeTab
};
changeTab = tab => {
this.setState({ activeTab: tab });
};
render() {
const { children } = this.props;
const { activeTab, loading } = this.state;
console.log('true or false before pass to children', loading)
return (
<div className="tabs">
{React.Children.map(children, child =>
React.cloneElement(child, {
loading,
activeTab,
changeTab: this.changeTab
})
)}
</div>
);
}
}
类选项卡扩展组件{
静态defaultProps={
活动选项卡:1
};
静态getDerivedStateFromProps(下一步,上一步){
if(nextrops.loading!==prevState.loading){
返回{
加载:nextrops.loading
}
}
}
状态={
activeTab:this.props.activeTab
};
changeTab=tab=>{
this.setState({activeTab:tab});
};
render(){
const{children}=this.props;
const{activeTab,load}=this.state;
console.log('传递给子级之前为true或false',正在加载)
返回(
{React.Children.map(Children,child=>
反应。克隆元素(儿童{
加载,
activeTab,
changeTab:this.changeTab
})
)}
);
}
}
但我把加载作为道具传递给Tab的子对象,也就是Tab,加载标志变成了false?我看不出这个问题
class Tab extends Component {
static Title = ({ children, tabId, activeTab, handleTabClick }) => {
return (
<div
className={`title ${tabId === activeTab ? "active" : ""}`}
onClick={handleTabClick}
>
{children}
</div>
);
};
static Content = ({ children, tabId, activeTab, loading }) => {
loading && 'Loading...' //won't work coz loading is always false, I wonder why
return tabId === activeTab ? (
<div className="content">{children}</div>
) : null;
};
render() {
return React.Children.map(this.props.children, child =>
React.cloneElement(child, {
handleTabClick: () => this.props.changeTab(this.props.id),
tabId: this.props.id,
activeTab: this.props.activeTab,
loading: this.props.loading // why always false?
})
);
}
}
类选项卡扩展组件{
静态标题=({children,tabId,activeTab,handleTabClick})=>{
返回(
{儿童}
);
};
静态内容=({children,tabId,activeTab,load})=>{
加载&“加载…”//不起作用,因为加载总是错误的,我想知道为什么
返回tabId==activeTab(
{儿童}
):null;
};
render(){
返回React.Children.map(this.props.Children,child=>
反应。克隆元素(儿童{
handleTabClick:()=>this.props.changeTab(this.props.id),
tabId:this.props.id,
activeTab:this.props.activeTab,
加载:this.props.load//为什么总是false?
})
);
}
}
我的演示
这个.props.loading在您的子组件中总是false
,因为当为true
时它甚至不会被渲染,因为数据在loading
为true
时是空的,所以数据
不会创建任何组件
您需要将加载检查移动到父组件,即使数据
为空,也会呈现该父组件。例如
编辑:
如果要分别获取每个选项卡的数据,则需要创建单独的API调用,一个用于获取选项卡标题以呈现选项卡标题,另一个用于获取活动选项卡的数据。初始设置为false时
state = {
loading: false,
data: []
}
加载组件后,将其模拟为true,然后模拟为false
async componentDidMount() {
this.setState({
loading: true
})
const data = await this.getData()
this.setState({
data,
loading: false
})
}
但您从未收到子组件中的组件状态更改
您可以使用
所以你可以试一下
class Tab extends Component {
componentWillReceiveProps(props) { //here you will get changes whenever state changes
let loading = props.loading
this.setState({loading});
}
render() {
return React.Children.map(this.props.children, child =>
React.cloneElement(child, {
handleTabClick: () => this.props.changeTab(this.props.id),
tabId: this.props.id,
activeTab: this.props.activeTab,
loading: this.state.loading //through state
})
);
}
}
没有人能回答这个问题?这会加载整个表,这不是我想要的,我想在用户切换选项卡时加载选项卡内容。然后你需要使用react router或一些支持该功能的选项卡库,或者更改选项卡
实现以仅呈现活动选项卡。因此,即使在您切换选项卡时,即使在获取数据后,您是否仍希望看到加载…
?您一次获取了所有选项卡的数据,因此我不确定您希望看到什么。是否要分别获取每个选项卡的数据?在这种情况下,需要多个API调用。在帖子中添加了一些细节。