如何使用一个与其他 JSON 对象的公共属性来获取一个 JSON 的特定属性?



我是新手.js在执行以下任务时遇到问题。

按照代码运行时,它显示无法使用setState并且应用中断。我有两个对象,obj2生成一个表3 columns.我需要使definition列的每个单元格都null不可点击,然后将我带到obj1中存在的team_wiki链接。

obj1: {
providers : [
{team_name : "XYZ", team_wiki : "https://example.com", team_id : 1},
{team_name : "ABC", team_wiki : "null", team_id : 2},
{team_name : "LMN", team_wiki : "https://example2.com", team_id : 3},
{team_name : "MNO", team_wiki : "https://example3.com", team_id : 4}
]
}
obj2: {
products : [
{team_name : "XYZ", definition : "this team handles XYZ products", metric_id : 101},
{team_name : "ABC", definition : "this team handles ABC products", metric_id : 201},
{team_name : "LMN", definition : "this team handles LMN products", metric_id : 301},
{team_name : "MNO", definition : "this team handles MNO products", metric_id : 401}
]
}

法典:

state = {
API_DATA : {},
TEAM_WIKI : ''
}
componentDidMount(){
// fetch the obj1 data and sets it to the state called API_DATA
}
wikiLink = (TEAM_NAME) {
// getting TEAM_NAME from a component inside the render method
const wiki = this.state.API_DATA.map(provider => {
if (provider.team_name = TEAM_NAME && provider.team_wiki !== null) {
return provider.team_wiki
}
})
.map(link => {
if (link !== undefined) {
return link
}
})
this.setState({
// TEAM_WIKI is a state { its a string } where i want to store the 
//team_wiki at last
TEAM_WIKI : wiki
})
}
render() {
return (
// i want to use it something like this
< href="this.state.TEAM_WIKI" onClick={this.wikiLink(TEAM_NAME)} />
) 
}

我觉得当第一次渲染发生时,this.wikiLink调用,而不是作为引用传递。我为什么这么认为?因为我在那里看到圆括号。此方法的主体包含对this.setState的调用,这意味着组件的状态在渲染时被交换,这违反了组件生命周期。

考虑一个案例:

class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
buttonClicked: false,
};
this.handleClickButton = this.handleClickButton.bind(this);
}
handleClickButton() {
this.setState({
buttonClicked: true,
});
}
render() {
return (
<button onClick={this.handleClickButton()}>click me</button>
);
}
}

有问题!表达式this.handleClickButton()是一个函数调用。其中,有一个状态更改指令。当代码尝试这样做时,React 会显示一条警告:

警告:setState(...(:在现有状态转换期间无法更新 (例如在render或其他组件的构造函数中(。呈现方法 应该是道具和状态的纯函数;构造函数的副作用是一种反模式, 但可以移动到componentWillMount.

相反,我们真正想要的是调用按钮单击时this.handleClickButton函数。为此,我们需要将对这个函数的引用传递给onClickprop,如下所示:

render() {
return (
<button onClick={this.handleClickButton}>click me</button>
);
}

请注意缺少圆括号。

那你应该怎么做呢?

有两种选择:

选项 1:onClick 中的匿名功能

而不是写作

render() {
return (
// i want to use it something like this
<a href="this.state.TEAM_WIKI" onClick={this.wikiLink(TEAM_NAME)} />
);
}

render() {
return (
// i want to use it something like this
<a href="this.state.TEAM_WIKI" onClick={() => this.wikiLink(TEAM_NAME)} />
);
}

这样,每次调用组件实例的方法render都会传递对就地声明的匿名函数的引用。然后,当用户决定单击时,将在某个不可预测的时间点调用此函数,即调度类型为"单击"的 MouseEvent。

选项 2:让 this.wikiLink(•( 返回一个函数!

函数返回函数的概念通常称为部分应用,或者在与此类似的情况下,通常称为闭包。因此,wikiLink函数将代替这个:

wikiLink(TEAM_NAME) {
// getting TEAM_NAME from a component inside the render method
const wiki = this.state.API_DATA.map(provider => {
if ((provider.team_name = TEAM_NAME && provider.team_wiki !== null)) {
return provider.team_wiki;
}
}).map(link => {
if (link !== undefined) {
return link;
}
});
this.setState({
// TEAM_WIKI is a state { its a string } where i want to store the
//team_wiki at last
TEAM_WIKI: wiki
});
}

看起来像这样:

wikiLink(TEAM_NAME) {
return () => {
// getting TEAM_NAME from a component inside the render method
const wiki = this.state.API_DATA.map(provider => {
if ((provider.team_name = TEAM_NAME && provider.team_wiki !== null)) {
return provider.team_wiki;
}
}).map(link => {
if (link !== undefined) {
return link;
}
});
this.setState({
// TEAM_WIKI is a state { its a string } where i want to store the
//team_wiki at last
TEAM_WIKI: wiki
});
};
}

这样当它被调用时,它会返回一个新函数。因为onClickprop 期望接收一个函数,所以我们解决了类型匹配的问题。因为我们用一些参数TEAM_NAME调用wikiLink,并且每次执行该函数时都会应用此参数,所以我们解决了保留上下文的问题。这不是很厉害吗!


为了更好地了解使用返回函数的函数,请查看此代码沙盒,第 16 行到第 23 行。希望它能给出一些关于在需要管理 React 组件状态的情况下如何利用闭包的想法。

干杯!

函数wikiLink不是类函数,并且未绑定到组件。您可以使用 es6 语法绑定 wikiLink,也可以将wikiLink绑定到组件。

要么wikiLink做类似的东西

wikiLink = (TEAM_NAME) => { // rest of your code

或: 在你的constructor你做一些类似的事情

constructor(){
this.wikiLink = this.wikiLink.bind(this)
}

在您的wikiLink中,您似乎正在尝试使用=>箭头功能快捷方式?

你在wikiLink函数中缺少一些东西。 你要么做类似的事情

function wikilink (Data) {//rest of your code}

或者上面的答案说了什么。

最新更新