const D3Animatables = () => {
const { subs_animatables, animatables } = useTracker(() => {
const
subs_animatables = Meteor.subscribe("animatablesPub"),
animatables = Animatables.find().fetch()
;
return {
subs_animatables,
animatables
};
});
const svgRef = useRef();
useEffect(() => {
const svg = select(svgRef.current);
svg
.selectAll("circle")
.data(animatables)
.join(
enter => enter
.append("circle")
.attr("r", a => a.radius)
.attr("cx", a => 100 * (animatables.indexOf(a) + 1))
)
}, [animatables]);
return <svg ref={svgRef}></svg>;
Your code will always return errors because you are displaying data while data is not ready yet!
You have to scenarios to solve this problem:
1):
//////////////////////////////////////////////////////////////////////////////////////////////
const D3Animatables = () => {
const { animatables } = useTracker(() => {
const animatables = Meteor.subscribe("animatablesPub") !== undefined ? Animatables.find().fetch() : undefined;
return {
animatables
};
});
const svgRef = useRef();
useEffect(() => {
const svg = select(svgRef.current);
svg
.selectAll("circle")
.data(animatables)
.join(
enter => enter
.append("circle")
.attr("r", a => a.radius)
.attr("cx", a => 100 * (animatables.indexOf(a) + 1))
)
}, [animatables]);
return animatables ? (<svg ref={svgRef}></svg>) : (<></>);
//////////////////////////////////////////////////////////////////////////////////////////////
2) Which I highly recommend:
//////////////////////////////////////////////////////////////////////////////////////////////
const D3Animatables = () => {
const ready = useTracker(() => Meteor.subscribe("animatablesPub").ready());
const {animatables } = useTracker(() => {
if(ready) {
return { Animatables.find().fetch() };
}
return { undefined };
}, [ready]);
const svgRef = useRef();
useEffect(() => {
const svg = select(svgRef.current);
svg
.selectAll("circle")
.data(animatables)
.join(
enter => enter
.append("circle")
.attr("r", a => a.radius)
.attr("cx", a => 100 * (animatables.indexOf(a) + 1))
)
}, [animatables]);
return ready ? (<svg ref={svgRef}></svg>) : (<></>);
//////////////////////////////////////////////////////////////////////////////////////////////
P.S: I did not check the useEffect() code so double check it after updating your code!