上下文提供程序中的 componentDidMount() 状态更改未触发子组件的重新渲染
Posted
技术标签:
【中文标题】上下文提供程序中的 componentDidMount() 状态更改未触发子组件的重新渲染【英文标题】:componentDidMount() State Change in Context Provider not triggering re-render on Child Components 【发布时间】:2020-11-06 14:12:44 【问题描述】:这是我的代码。一直试图让它工作4天。从函数组件到类组件,再到介于两者之间的所有东西,我都尝试过。不知所措。我无法在构造函数中正确设置状态,因为它是异步的,但是在放入 componentDidMount() 时不会重新渲染
编辑:是的,我知道有些代码是多余的。我对其进行了更改以隔离错误并删除了 addParams() 逻辑以及其他一些内容。
import React, Component from "react";
import axios from "axios";
export const ListContext = React.createContext();
class ListContextProvider extends Component
constructor()
super();
this.state = cards: , params: ;
addParams(parameters)
return parameters;
getCards()
let parameters = this.addParams( last_name__icontains: "smith" );
console.log(parameters);
axios(
method: "get",
url: "http://127.0.0.1:8000/charges/cardsapi/",
params: parameters,
).then((response) =>
let cards = Object.values(response.data.results);
let cardsState = Object.assign(, cards);
this.setState( cards: cardsState );
console.log(this);
console.log(this.state);
);
componentDidMount()
console.log("mounted");
this.getCards();
render()
return (
<ListContext.Provider value=this.state>
this.props.children
</ListContext.Provider>
);
export ListContextProvider ;
然后是消费者:
export default function DataTable(context)
let cards = context;
const rows = [];
const headerCells = [];
if (cards.length > 1)
for (let field in cards[0])
headerCells.push(<TableCell key=field>field</TableCell>);
for (let row of cards)
const cells = [];
for (const [key, value] of Object.entries(row))
cells.push(<TableCell key=key>value</TableCell>);
rows.push(<TableRow key=cells[0].props.children>cells</TableRow>);
return (
<Table>
<TableHead>
<TableRow key="header">headerCells</TableRow>
</TableHead>
<TableBody>rows</TableBody>
</Table>
);
else
return (
<Table>
<tbody>
<tr>
<td>Empty</td>
</tr>
</tbody>
</Table>
);
【问题讨论】:
我建议将 onLoad 标志添加到 ListContextProvider 组件的状态。只有在 axios 返回时,它才会变为 true。在渲染器函数中,您在数据不可用时返回 - 或做任何事情。但请确保仅在数据可用时渲染 我认为这是个好建议。这就是我要尝试的。谢谢。 我使用 useContext() 钩子解决了这个问题。我不知道为什么 Consumer Context 不起作用,但无论如何钩子更干净。 你确定你引用了正确的this
吗?您正在为render
和componentDidMount
使用普通函数,因此它们有自己的this
上下文。
哦是的,即使在嵌套的axios调用中this
也绑定了ListContextProvider对象。它确实呈现正确,只是没有更新状态更改。我能够使用useContext()
钩子和等待addParams()
完成状态更新的异步componentDidMount()
来解决这个问题。 OP里面的代码有点不清楚,拿出了很多本来想做的事情。让我重新发布有效的方法。
【参考方案1】:
这行得通:
import React, Component from "react";
import axios from "axios";
let ListContext = React.createContext();
class ListContextProvider extends Component
constructor()
super();
this.state = cards: [], params: ;
addParams(parameters)
this.setState( params: parameters );
getCards()
let parameters = this.state.params;
console.log(parameters);
axios(
method: "get",
url: "http://127.0.0.1:8000/charges/cardsapi/",
params: parameters,
).then((response) =>
let cardsState = Object.values(response.data.results);
this.setState( cards: cardsState );
);
async componentDidMount()
await this.addParams( last_name__icontains: "shaer" );
console.log("mounted");
this.getCards();
render()
return (
<ListContext.Provider value=this.state>
this.props.children
</ListContext.Provider>
);
export ListContextProvider, ListContext ;
【讨论】:
以上是关于上下文提供程序中的 componentDidMount() 状态更改未触发子组件的重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
上下文提供程序中的 componentDidMount() 状态更改未触发子组件的重新渲染