Investigating JavaScript prime number widget implementation.
This is not a real pr, the purpose is more for talking about the ipyreact pattern. The Situation: I have a widget that contains a button. When the button is clicked, the value count increases. A message is shown that notifies if the number of total clicks is a prime number or not.
In the first widget, I use a prime_message traitlet to communicate with the user.
When the button is pressed, a new message is calculated and displayed correctly.
The message can also be manipulated by primepy.prime_message = "Hello World"
Now I want to do the same thing, but make the calculations in JavaScript.
That also works, but I don't know how to allow the user to manipulate the message by e.g. primejs.prime_message = "Hello World".
@paddymul : would you be interested in investigating how the
prime_message = isPrimeNumber(count);
return <span> {prime_message} </span>;
pattern can be used in a way that prime_message = isPrimeNumber(count); only gets called on number change?
I think you want to use the setter for primeMessage, not set it directly.
So
export const MyUpdater = ({ count, prime_message}) => {
prime_message = isPrimeNumber(count); //This feels very un-reactlike because you are modifying a property inplace
return <span> {prime_message} </span>;
};
Should be something like
export const MyUpdater = ({ count, prime_message}) => {
return <span> {prime_message} </span>;
};
export default function ({ on_count, count, prime_message, on_prime_message}) {
on_prime_message(isPrimeNumber(count));
return (
<div>
<button onClick={() => on_count(count + 1)}>{count} times clicked</button>
<br />
<MyUpdater count={count} prime_message = {prime_message}/>
</div>
);
}
"""
I don't think the above will work though, because it will result in a loop.
I'm not sure I have a good answer.
Thanks for your suggestion.
I just included your suggestions, it did not result in a loop, however the line on_prime_message(isPrimeNumber(count));
does not allow setting the message by primejs.prime_message = "Hello World":
import ipyreact
from traitlets import Any , Int
class PrimeJavaScriptWidget(ipyreact.ReactWidget):
prime_message = Any("Click the Button").tag(sync=True) # <- TODO: this message does not show up because prime_message is overwritten
count = Int(0).tag(sync=True)
_esm = """
import * as React from "react";
function isPrimeNumber(n) {
for (let i = 2; i < n; i++) {
if (n % i === 0) {
return "No 🌐🧊🧊🧊";
}
}
return "Yes 🌐✅✅✅";
}
export const MyUpdater = ({ count, prime_message}) => {
return <span> {prime_message} </span>;
};
export default function ({ on_count, count, prime_message, on_prime_message}) {
on_prime_message(isPrimeNumber(count));
return (
<div>
<button onClick={() => on_count(count + 1)}>{count} times clicked</button>
<br />
<MyUpdater count={count} prime_message = {prime_message}/>
</div>
);
}
"""
primejs = PrimeJavaScriptWidget()
primejs.prime_message = "Hello World" # <- TODO
primejs