目前处理个人项目并且我收到此错误
Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Please check the code for the Graph component.
我的App component.
也遇到了同样的问题我已经对这个问题进行了一些阅读,但我对于我的代码具体问题并不明智。
非常感谢任何见解。
这是running project (with sourcecode) on CodeSnadbox.io的链接,我也链接了下面的违规代码。
以下是Graph Component
import React, { Component } from "react";
import { render } from "react-dom";
import { Line, Doughnut, Bar } from "react-chartjs-2";
import moment from "moment";
import PropTypes from "prop-types";
import styleConstants from "../misc/style_constants.js";
class Graph extends Component {
constructor(props) {
super(props);
this.state = {
label: "default",
dataset: [],
labels: []
};
}
/**
* https://min-api.cryptocompare.com/ for documentation
*/
async getHistoryData(ticker = "BTC", currency = "USD", filter = "close") {
try {
let response = await fetch(
`https://min-api.cryptocompare.com/data/histoday?fsym=${ticker}&tsym=${currency}&limit=60&aggregate=3&e=CCCAGG`
);
const responseJson = await response.json();
const dataset = responseJson.Data.map(data => {
return data[filter];
});
const labels = responseJson.Data.map(data => {
return moment(new Date(data.time * 1000)).format("MMM Do YY");
});
this.setState({ dataset: dataset });
this.setState({ labels: labels });
} catch (error) {
console.log(error);
}
}
componentDidMount() {
const { ticker, currency, filter } = this.props;
this.getHistoryData(ticker, currency, filter);
}
render() {
const { label, graphType } = this.props;
const { dataset, labels } = this.state;
const options = {
legend: {
fontColor: styleConstants.get("Dark")
},
scales: {
yAxes: [
{
ticks: {
fontColor: styleConstants.get("Light"),
beginAtZero: true,
callback: function(value, index, values) {
if (parseInt(value) >= 1000) {
return (
"$" + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
);
} else {
return "$" + value;
}
}
}
}
],
xAxes: [
{
ticks: {
fontColor: styleConstants.get("Light"),
fontSize: 10,
stepSize: 1,
beginAtZero: true
}
}
]
}
};
const data = {
labels: labels,
datasets: [
{
label: label,
fill: true,
lineTension: 0.1,
backgroundColor: styleConstants.get("Medium"),
borderColor: styleConstants.get("Medium"),
borderCapStyle: "butt",
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: "miter",
pointBorderColor: styleConstants.get("Light"),
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: dataset
}
]
};
return <Line data={data} options={options} />;
// switch (graphType) {
// case "line":
// return <Line data={data} options={options} />;
// break;
// case "bar":
// return <Bar data={data} options={options} />;
// break;
// case "doughnut":
// return <Doughnut data={data} options={options} />;
// break;
// default:
// return null;
// }
}
}
Graph.propTypes = {
label: PropTypes.string,
graphType: PropTypes.string
};
Graph.defaultProps = {
label: "Default String",
graphType: "Default String"
};
export default Graph;
以下是App Component
import React, { Component } from "react";
import { render } from "react-dom";
import styled, { css } from "styled-components";
import styleConstants from "../misc/style_constants.js";
import Overview from "../components/Overview";
import Panel from "../components/Panel";
import Table from "../components/Table";
import Options from "./Options";
import Graph from "./Graph";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
selectedTicker: "BTC",
currency: "USD",
tickers: [],
overview: []
};
this.updateTicker = this.updateTicker.bind(this);
this.createGraph = this.createGraph.bind(this);
}
updateTicker(selectedValue) {
const { value } = selectedValue;
this.setState({ selectedTicker: value });
}
async getTickers() {
try {
const response = await fetch('https://api.coinmarketcap.com/v1/ticker/')
const responseJSON = await response.json();
this.setState({ tickers: responseJSON });
} catch (error) {
console.log("App getTickers() ", error);
}
}
async getOverviewData() {
try {
const response = await fetch(`https://api.coinmarketcap.com/v1/global/?convert=${this.state.currency}`)
const responseJSON = await response.json();
this.setState({ overview: responseJSON });
} catch (error) {
console.log("App getOverviewData() ", error);
}
}
componentDidMount() {
this.getTickers();
this.getOverviewData();
}
createGraph(ticker = "", currency = "", graphType = "", label = "", filter = "") {
return (
<Graph
filter={filter}
ticker={ticker}
currency={currency}
graphType={graphType}
label={label}
/>
)
}
render() {
const { selectedTicker, currency } = this.state;
const Container = styled.div`
input:focus,
select:focus,
textarea:focus,
`;
const Title = styled.h1`
text-align: center;
color: ${styleConstants.get('Yellow')};
`;
const LightSpan = styled.span`
font-weight: 200;
`;
return (
<Container>
<Title>
Coin:<LightSpan>Dash</LightSpan>
</Title>
<Overview {...this.state.overview} />
<Options
selectedValue={this.state.selectedTicker}
values={this.state.tickers.map(data => {
return data.symbol;
})}
labels={
this.state.tickers.map(data => {
return data.id;
})
}
updateTicker={this.updateTicker} />
<Panel label={"Price Action"} content={this.createGraph(selectedTicker, currency, 'line', "Close", "close")} />
<Panel label={"Highest Price"} content={this.createGraph(selectedTicker, currency, 'bar', "High", "high")} />
<Panel label={"Lowest Price"} content={this.createGraph(selectedTicker, currency, 'bar', "Low", "low")} />
<Panel label={"Top Ten List"} content={
<Table header={["Rank", "Name", "Price", "Change(24 Hour)"]} collection={this.state.tickers} />
} />
</Container>
);
}
}
答案 0 :(得分:1)
问题是由render
App
方法中定义的无状态功能组件引起的。如果在App
类之外定义以下函数,则会修复错误:
const Container = styled.div`
input:focus,
select:focus,
textarea:focus,
`;
const Title = styled.h1`
text-align: center;
color: ${styleConstants.get('Yellow')};
`;
const LightSpan = styled.span`
font-weight: 200;
`;
export default class App extends Component {
..
失败的原因是本地创建的SFC对每个渲染进行了更改,这导致它们卸载并重新安装,即使渲染保持不变。 Table
组件中还有一些其他本地SFC,它们没有发出任何警告,但会造成不必要的重新安装。
更新:这是一个难题,但剩下的警告来自其中一个测试:
describe("App", () => {
it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
});
在异步操作完成之前卸载组件时,这是有道理的。
这是一个工作沙箱:https://codesandbox.io/s/24o6vp4rzp(我还删除了content={..}
中的箭头功能,因为它需要是一个值)