异步更新渲染组件 Prop 值
Update Rendered Component Prop Value Async
我创建了几个包含财务数据的列表项,我想使用 react-sparklines 在侧面显示一个迷你图。
所以我试图在映射数组时获取图形数据,因为检索数据可能需要一些时间,但似乎我无法让图形组件正确更新道具值。
从 fetch 中检索到数据后,如何更新 Sparklines 组件中的道具数据?这可能吗?
这是我的代码示例
class CurrencyList extends Component {
currencyGraph(symbol) {
return fetch(baseURL, {
method: 'POST',
headers: {
'Authorization': 'JWT ' + token || undefined, // will throw an error if no login
},
body: JSON.stringify({'symbol': symbol})
})
.then(handleApiErrors)
.then(response => response.json())
.then(function(res){
if (res.status === "error") {
var error = new Error(res.message)
error.response = res.message
throw error
}
return res.graph_data
})
.catch((error) => {throw error})
}
render () {
topCurrencies.map((currency,i) => {
return (
<ListItem key={i} button>
<Sparklines data={this.currencyGraph(currency.symbol)} >
<SparklinesLine style={{ stroke: "white", fill: "none" }} />
</Sparklines>
<ListItemText primary={currency.symbol} />
</ListItem>
)
})
}
}
您不能 return 来自异步函数的数据。相反,当您的加载请求完成时,将数据设置为触发组件呈现的状态。请注意,在下面的测试用例中,它会呈现一个占位符,直到数据准备就绪。
Item = props => <div>{props.name}</div>;
class Test extends React.Component {
state = {
data: ''
}
componentDidMount() {
// Simulate a remote call
setTimeout(() => {
this.setState({
data: 'Hi there'
});
}, 1000);
}
render() {
const { data } = this.state;
return data ? <Item name={this.state.data} /> : <div>Not ready yet</div>;
}
}
ReactDOM.render(
<Test />,
document.getElementById('container')
);
我会用我自己的组件包装这个组件并接受数据作为道具。
在父组件中,只有当我准备好数据并在每次迭代时将相关数据传递给每个组件时,我才会呈现列表。
Here is a running small example
const list = [
{
key: 1,
data: [5, 10, 5, 20]
},
{
key: 2,
data: [15, 20, 5, 50]
},
{
key: 3,
data: [1, 3, 5, 8]
}
];
class MySparklines extends React.Component {
render() {
const { data } = this.props;
return (
<Sparklines data={data} limit={5} height={20}>
<SparklinesLine style={{ fill: "#41c3f9" }} />
</Sparklines>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
dataList: []
}
}
componentDidMount() {
setTimeout(() => {
this.setState({ dataList: list });
}, 1500);
}
renderCharts = () => {
const { dataList } = this.state;
return dataList.map((d) => {
return(
<MySparklines key={d.key} data={d.data} />
);
})
}
render() {
const { dataList } = this.state;
return (
<div>
{
dataList.length > 0 ?
this.renderCharts() :
<div>Loading...</div>
}
</div>
);
}
}
我创建了几个包含财务数据的列表项,我想使用 react-sparklines 在侧面显示一个迷你图。 所以我试图在映射数组时获取图形数据,因为检索数据可能需要一些时间,但似乎我无法让图形组件正确更新道具值。
从 fetch 中检索到数据后,如何更新 Sparklines 组件中的道具数据?这可能吗?
这是我的代码示例
class CurrencyList extends Component {
currencyGraph(symbol) {
return fetch(baseURL, {
method: 'POST',
headers: {
'Authorization': 'JWT ' + token || undefined, // will throw an error if no login
},
body: JSON.stringify({'symbol': symbol})
})
.then(handleApiErrors)
.then(response => response.json())
.then(function(res){
if (res.status === "error") {
var error = new Error(res.message)
error.response = res.message
throw error
}
return res.graph_data
})
.catch((error) => {throw error})
}
render () {
topCurrencies.map((currency,i) => {
return (
<ListItem key={i} button>
<Sparklines data={this.currencyGraph(currency.symbol)} >
<SparklinesLine style={{ stroke: "white", fill: "none" }} />
</Sparklines>
<ListItemText primary={currency.symbol} />
</ListItem>
)
})
}
}
您不能 return 来自异步函数的数据。相反,当您的加载请求完成时,将数据设置为触发组件呈现的状态。请注意,在下面的测试用例中,它会呈现一个占位符,直到数据准备就绪。
Item = props => <div>{props.name}</div>;
class Test extends React.Component {
state = {
data: ''
}
componentDidMount() {
// Simulate a remote call
setTimeout(() => {
this.setState({
data: 'Hi there'
});
}, 1000);
}
render() {
const { data } = this.state;
return data ? <Item name={this.state.data} /> : <div>Not ready yet</div>;
}
}
ReactDOM.render(
<Test />,
document.getElementById('container')
);
我会用我自己的组件包装这个组件并接受数据作为道具。
在父组件中,只有当我准备好数据并在每次迭代时将相关数据传递给每个组件时,我才会呈现列表。
Here is a running small example
const list = [
{
key: 1,
data: [5, 10, 5, 20]
},
{
key: 2,
data: [15, 20, 5, 50]
},
{
key: 3,
data: [1, 3, 5, 8]
}
];
class MySparklines extends React.Component {
render() {
const { data } = this.props;
return (
<Sparklines data={data} limit={5} height={20}>
<SparklinesLine style={{ fill: "#41c3f9" }} />
</Sparklines>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
dataList: []
}
}
componentDidMount() {
setTimeout(() => {
this.setState({ dataList: list });
}, 1500);
}
renderCharts = () => {
const { dataList } = this.state;
return dataList.map((d) => {
return(
<MySparklines key={d.key} data={d.data} />
);
})
}
render() {
const { dataList } = this.state;
return (
<div>
{
dataList.length > 0 ?
this.renderCharts() :
<div>Loading...</div>
}
</div>
);
}
}