Skip to content

Conversation

kolibril13
Copy link
Collaborator

No description provided.

@kolibril13 kolibril13 marked this pull request as draft April 28, 2023 12:14
@kolibril13
Copy link
Collaborator Author

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?

@kolibril13 kolibril13 changed the title Add comparison example Investigating JavaScript prime number widget implementation. Apr 28, 2023
@paddymul
Copy link
Collaborator

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.

@kolibril13
Copy link
Collaborator Author

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

@maartenbreddels maartenbreddels force-pushed the master branch 3 times, most recently from 885d994 to 511a7ba Compare October 24, 2024 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants