Hack to render

I have a signal pValue that takes values on input blur
<input
type="number"
onBlur={(e) => {
setPValue(Number(e.target.value));
console.log(pValue());
setRenderGraph(!renderGraph());
}}
class="stakeAmountInput"
/>
<input
type="number"
onBlur={(e) => {
setPValue(Number(e.target.value));
console.log(pValue());
setRenderGraph(!renderGraph());
}}
class="stakeAmountInput"
/>
it's a prop for a component rendered in the return <Graph P={pValue()}/> This component is not re-render on pValue change, so I did a hack
{renderGraph() && <Graph P={pValue()} />}
{!renderGraph() && pValue() && <Graph P={pValue()} />}

{renderGraph() && <Graph P={pValue()} />}
{!renderGraph() && pValue() && <Graph P={pValue()} />}

It's ugly but it works. Why is happening this and how I can solve it?
9 Replies
REEEEE
REEEEE12mo ago
how are you reading P inside of the Graph? Solid doesn't (generally) rerender so the issue could be where you're using the P prop
Mentasuave01
Mentasuave01OP12mo ago
let P = props.P; and then I use P in d3js do create some graphs
REEEEE
REEEEE12mo ago
okay but where and how is the code written? For example, if you do something like this it won't work:
const Graph = (props) => {
let P = props.P

d3.xyz

return (
...Some elements and ui
)
}
const Graph = (props) => {
let P = props.P

d3.xyz

return (
...Some elements and ui
)
}
In order for it to be reactive, you need to read props.P in a reactive scope like the JSX or an effect Unlike React, Solid doesn't rerender the whole component. So the P inside Graph will always be the initial value of props.P when the component was mounted.
Mentasuave01
Mentasuave01OP12mo ago
so if for example I add console.log(props.P) it should re render? just as a vague example
REEEEE
REEEEE12mo ago
no, you would have to wrap the console.log in a createEffect
createEffect(() => {
console.log(props.P)
})
createEffect(() => {
console.log(props.P)
})
Now it will log any time props.P changes
Mentasuave01
Mentasuave01OP12mo ago
not working, this is my createEffect
createEffect(() => {
console.log(props.P);
d3.select(ref()).selectAll("*").remove();
let i = 0.08;

let margin = { top: 30, right: 20, bottom: 30, left: 50 },
width = 400 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;

let x = d3
.scaleLinear()
.domain([0, 3 * 365])
.range([0, width]);
let y = d3
.scaleLinear()
.domain([P, P * 1.25])
.range([height, 0]);

let xAxis = d3.axisBottom(x);
let yAxis = d3.axisLeft(y);

let y1line = d3
.line<{ x: number; y1: number }>()
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y1);
});
let y2line = d3
.line<{ x: number; y2: number }>()
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y2);
});

let svg = d3
.select(ref())
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let data = [];
for (let xVal = 0; xVal <= 3 * 365; xVal++) {
data.push({
x: xVal,
y1: xVal * (i / 365) * P + P,
y2: P * Math.pow(1 + i / 365, xVal),
});
}

let y1Path = svg
.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "blue")
.attr("stroke-width", 1.5)
.attr("d", y1line);

let hoverText = svg.append("text");

let overlay = svg
.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");

overlay
.on("mousemove", function (event) {
let x0 = x.invert(d3.pointer(event, this)[0]);
let i = d3.bisectLeft(
data.map((d) => d.x),
x0,
1
);
let d0 = data[i - 1];
let d1 = data[i];
let d = x0 - d0.x > d1.x - x0 ? d1 : d0;
setYValues({ y1: d.y1, y2: d.y2 });
})
.on("mouseout", function () {
hoverText.attr("visibility", "hidden");
});

svg
.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-width", 1.5)
.attr("d", y2line);
svg
.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

svg.append("g").call(yAxis);
}, [props.P]);
createEffect(() => {
console.log(props.P);
d3.select(ref()).selectAll("*").remove();
let i = 0.08;

let margin = { top: 30, right: 20, bottom: 30, left: 50 },
width = 400 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;

let x = d3
.scaleLinear()
.domain([0, 3 * 365])
.range([0, width]);
let y = d3
.scaleLinear()
.domain([P, P * 1.25])
.range([height, 0]);

let xAxis = d3.axisBottom(x);
let yAxis = d3.axisLeft(y);

let y1line = d3
.line<{ x: number; y1: number }>()
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y1);
});
let y2line = d3
.line<{ x: number; y2: number }>()
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y2);
});

let svg = d3
.select(ref())
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let data = [];
for (let xVal = 0; xVal <= 3 * 365; xVal++) {
data.push({
x: xVal,
y1: xVal * (i / 365) * P + P,
y2: P * Math.pow(1 + i / 365, xVal),
});
}

let y1Path = svg
.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "blue")
.attr("stroke-width", 1.5)
.attr("d", y1line);

let hoverText = svg.append("text");

let overlay = svg
.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");

overlay
.on("mousemove", function (event) {
let x0 = x.invert(d3.pointer(event, this)[0]);
let i = d3.bisectLeft(
data.map((d) => d.x),
x0,
1
);
let d0 = data[i - 1];
let d1 = data[i];
let d = x0 - d0.x > d1.x - x0 ? d1 : d0;
setYValues({ y1: d.y1, y2: d.y2 });
})
.on("mouseout", function () {
hoverText.attr("visibility", "hidden");
});

svg
.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-width", 1.5)
.attr("d", y2line);
svg
.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

svg.append("g").call(yAxis);
}, [props.P]);
REEEEE
REEEEE12mo ago
what isn't working? Also, createEffect doesn't have a dependency array. You can remove that Also, you're access P but it's not in the effect
y2: P * Math.pow(1 + i / 365, xVal),
y2: P * Math.pow(1 + i / 365, xVal),
the P here isn't in the effect. Add let P = props.P inside the effect
Mentasuave01
Mentasuave01OP12mo ago
that solved it, 1000 times thanks, now I know a little better how solid work. Thanks again budy
REEEEE
REEEEE12mo ago
No problem!
Want results from more Discord servers?
Add your server