#reactjs #mobx #use-effect
#reactjs #mobx #use-effect
Вопрос:
https://codesandbox.io/s/stacked-bar-useeffect-upbf8
В приведенном выше коде ключ props изменяется, а график обновляется, но предыдущая итерация все еще отображается и создает беспорядок. Где я ошибаюсь? Я попытался выполнить очистку и использовал минимальный код, необходимый для просмотра того, что я могу обновить, но я все равно получаю тот же результат.
<Observer>
{() => <BarStacked keys={store.keys} store={store} />}
</Observer>
const BarStacked = (props) => {
var max_y = 100;
const margin = props.store.graphPreferences.margin;
const width = props.store.graphPreferences.width;
const height = props.store.graphPreferences.height;
const svgRefHours = useRef();
useEffect(() => {
const svg = d3.select(svgRefHours.current);
const chart = svg
.append("g")
.attr("transform", `translate(${margin}, ${margin})`);
const stackGenerator = stack()
.keys(props.store.keys)
.order(stackOrderAscending);
const layers = stackGenerator(data);
const extent = [
0,
max(layers, (layer) => max(layer, (sequency) => sequency[1]))
];
const xScale = d3
.scaleBand()
.domain(data.map((d) => d.dayofmonth))
.range([0, width])
.padding(0.25);
const xAxis = axisBottom(xScale);
const yScale = d3.scaleLinear().domain(extent).range([height, 0]);
// vertical grid lines
const makeXLines = () => d3.axisBottom().scale(xScale);
const makeYLines = () => d3.axisLeft().scale(yScale);
chart
.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
chart.append("g").call(d3.axisLeft(yScale));
// vertical grid lines
chart
.append("g")
.attr("class", "grid")
.attr("transform", `translate(0, ${height})`)
.call(makeXLines().tickSize(-height, 0, 0).tickFormat(""));
chart
.append("g")
.attr("class", "grid")
.call(makeYLines().tickSize(-width, 0, 0).tickFormat(""));
const barGroups = chart.selectAll().data(data).enter().append("g");
barGroups
.selectAll(".layer")
.data(layers)
.join("g")
.attr("class", "layer")
.attr("fill", (layer) => props.store.colors[layer.key])
.selectAll("rect")
.data((layer) => layer)
.join("rect")
.attr("x", (sequence) => xScale(sequence.data.dayofmonth))
.attr("width", xScale.bandwidth())
.attr("y", (sequence) => yScale(sequence[1]))
.attr("height", (sequence) => yScale(sequence[0]) - yScale(sequence[1]))
.on("mouseover", function () {
// d3.selectAll(".dayofmonth").attr("fill", )
d3.select(this).attr("fill", "blue");
})
.on("mouseout", function () {
d3.select(this).attr("fill", (layer) => props.store.colors[layer.key]);
});
const yAxis = axisLeft(yScale);
svg.select(".y-axis").call(yAxis);
svg
.append("text")
.attr("class", "label")
.attr("x", -(height / 2) - margin)
.attr("y", margin / 2.4)
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.text("Number of Tracks");
svg
.append("text")
.attr("class", "label")
.attr("x", width / 2 margin)
.attr("y", height margin * 1.7)
.attr("text-anchor", "middle")
.text("Day of the Month");
svg
.append("text")
.attr("class", "title")
.attr("x", width / 2 margin)
.attr("y", 40)
.attr("text-anchor", "middle")
.text("Tracks per day of the month");
return () => {};
}, [
height,
max_y,
props,
width,
margin,
props.store.colors,
props.store.keys
]);
return (
<svg ref={svgRefHours}>
<g className="x-axis" />
<g className="y-axis" />
</svg>
);
};
** редактирование заключалось в добавлении кода, ссылка по-прежнему доступна для получения дополнительной информации, поскольку я не был уверен, что имеет отношение к вопросу.
Комментарии:
1. Должно ли быть возможно просматривать только один датчик одновременно? Похоже, вам нужно очистить SVG, прежде чем пытаться снова отобразить его.
2. svg-код в порядке, при первоначальном рендеринге он работает нормально. Если я настрою ключ вручную, он загружается так, как должен. Предыдущий рендеринг просто не исчезает.