React set state based on prime number detection












0














I need to change state in a React component depending on the number output by clicking a button. The button increments a counter in state. If the number is prime, it should change the isPrime state to true; if not isPrime should be false.



  class Counter extends Component {

constructor(props) {
super(props);
this.state = {
count:0,
isPrime: false
};
}

checkPrime = (num) => {
if (num === 1) return false;
if (num === 2) return true;
for(var i = 2; i < num; i++) {
if(num % i === 0) {
return false; // it isn't prime
}
}
return true; //it is prime
}

incrementItem = () => {
this.setState((prevState, { count }) => ({
count: prevState.count + 1
}));
if (this.checkPrime(this.state.count)) {
this.setState({ isPrime: true });
}
else {
this.setState({ isPrime: false });
}
}


render() {
return (
<div id="mainDiv" className={this.state.isPrime ? 'bgPrime' : ''}>
<button onClick={this.incrementItem}>Click me</button>
{<h2>{ this.state.count }</h2> }
</div>
);
}
}

export default Counter;


In the incrementItem function, I couldn't get the following syntax to work as suggested here:



    this.setState((prevState, { isPrime }) => {
isPrime: true
});
// ('Expected an assignment or function call and instead saw an expression no-unused-expressions')









share|improve this question




















  • 1




    Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
    – Tex
    Nov 20 '18 at 20:26










  • I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
    – numbers1311407
    Nov 20 '18 at 20:27












  • Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
    – David
    Nov 20 '18 at 20:43










  • Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
    – Tex
    Nov 20 '18 at 20:43










  • I thought the point of the function to set state was that it would make it happen immediately
    – David
    Nov 20 '18 at 20:45
















0














I need to change state in a React component depending on the number output by clicking a button. The button increments a counter in state. If the number is prime, it should change the isPrime state to true; if not isPrime should be false.



  class Counter extends Component {

constructor(props) {
super(props);
this.state = {
count:0,
isPrime: false
};
}

checkPrime = (num) => {
if (num === 1) return false;
if (num === 2) return true;
for(var i = 2; i < num; i++) {
if(num % i === 0) {
return false; // it isn't prime
}
}
return true; //it is prime
}

incrementItem = () => {
this.setState((prevState, { count }) => ({
count: prevState.count + 1
}));
if (this.checkPrime(this.state.count)) {
this.setState({ isPrime: true });
}
else {
this.setState({ isPrime: false });
}
}


render() {
return (
<div id="mainDiv" className={this.state.isPrime ? 'bgPrime' : ''}>
<button onClick={this.incrementItem}>Click me</button>
{<h2>{ this.state.count }</h2> }
</div>
);
}
}

export default Counter;


In the incrementItem function, I couldn't get the following syntax to work as suggested here:



    this.setState((prevState, { isPrime }) => {
isPrime: true
});
// ('Expected an assignment or function call and instead saw an expression no-unused-expressions')









share|improve this question




















  • 1




    Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
    – Tex
    Nov 20 '18 at 20:26










  • I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
    – numbers1311407
    Nov 20 '18 at 20:27












  • Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
    – David
    Nov 20 '18 at 20:43










  • Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
    – Tex
    Nov 20 '18 at 20:43










  • I thought the point of the function to set state was that it would make it happen immediately
    – David
    Nov 20 '18 at 20:45














0












0








0







I need to change state in a React component depending on the number output by clicking a button. The button increments a counter in state. If the number is prime, it should change the isPrime state to true; if not isPrime should be false.



  class Counter extends Component {

constructor(props) {
super(props);
this.state = {
count:0,
isPrime: false
};
}

checkPrime = (num) => {
if (num === 1) return false;
if (num === 2) return true;
for(var i = 2; i < num; i++) {
if(num % i === 0) {
return false; // it isn't prime
}
}
return true; //it is prime
}

incrementItem = () => {
this.setState((prevState, { count }) => ({
count: prevState.count + 1
}));
if (this.checkPrime(this.state.count)) {
this.setState({ isPrime: true });
}
else {
this.setState({ isPrime: false });
}
}


render() {
return (
<div id="mainDiv" className={this.state.isPrime ? 'bgPrime' : ''}>
<button onClick={this.incrementItem}>Click me</button>
{<h2>{ this.state.count }</h2> }
</div>
);
}
}

export default Counter;


In the incrementItem function, I couldn't get the following syntax to work as suggested here:



    this.setState((prevState, { isPrime }) => {
isPrime: true
});
// ('Expected an assignment or function call and instead saw an expression no-unused-expressions')









share|improve this question















I need to change state in a React component depending on the number output by clicking a button. The button increments a counter in state. If the number is prime, it should change the isPrime state to true; if not isPrime should be false.



  class Counter extends Component {

constructor(props) {
super(props);
this.state = {
count:0,
isPrime: false
};
}

checkPrime = (num) => {
if (num === 1) return false;
if (num === 2) return true;
for(var i = 2; i < num; i++) {
if(num % i === 0) {
return false; // it isn't prime
}
}
return true; //it is prime
}

incrementItem = () => {
this.setState((prevState, { count }) => ({
count: prevState.count + 1
}));
if (this.checkPrime(this.state.count)) {
this.setState({ isPrime: true });
}
else {
this.setState({ isPrime: false });
}
}


render() {
return (
<div id="mainDiv" className={this.state.isPrime ? 'bgPrime' : ''}>
<button onClick={this.incrementItem}>Click me</button>
{<h2>{ this.state.count }</h2> }
</div>
);
}
}

export default Counter;


In the incrementItem function, I couldn't get the following syntax to work as suggested here:



    this.setState((prevState, { isPrime }) => {
isPrime: true
});
// ('Expected an assignment or function call and instead saw an expression no-unused-expressions')






javascript reactjs






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 19:33

























asked Nov 20 '18 at 20:21









David

5061126




5061126








  • 1




    Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
    – Tex
    Nov 20 '18 at 20:26










  • I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
    – numbers1311407
    Nov 20 '18 at 20:27












  • Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
    – David
    Nov 20 '18 at 20:43










  • Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
    – Tex
    Nov 20 '18 at 20:43










  • I thought the point of the function to set state was that it would make it happen immediately
    – David
    Nov 20 '18 at 20:45














  • 1




    Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
    – Tex
    Nov 20 '18 at 20:26










  • I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
    – numbers1311407
    Nov 20 '18 at 20:27












  • Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
    – David
    Nov 20 '18 at 20:43










  • Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
    – Tex
    Nov 20 '18 at 20:43










  • I thought the point of the function to set state was that it would make it happen immediately
    – David
    Nov 20 '18 at 20:45








1




1




Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
– Tex
Nov 20 '18 at 20:26




Wrap { isPrime: true } in parens: this.setState((prevState, { isPrime }) => ({ isPrime: true});.
– Tex
Nov 20 '18 at 20:26












I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
– numbers1311407
Nov 20 '18 at 20:27






I don't know what's going on with that suggestion, but if you pass a function to setState it receives state and props as arguments. The first argument is always "prevState". And as Tex suggests, the syntax is incorrect because the {} are being interpreted as a function block. You'd have to wrap them in params.
– numbers1311407
Nov 20 '18 at 20:27














Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
– David
Nov 20 '18 at 20:43




Thanks but when I do that, it complains about the semicolon (' Parsing error: Unexpected token, expected ",") .
– David
Nov 20 '18 at 20:43












Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
– Tex
Nov 20 '18 at 20:43




Although after looking at the code again, I'm not sure why you'd want to do that, and the code example looks iffy in a couple of places.this.setState((prevState, { count }) could just be this.setState((prevState), and setState is asynchronous, meaning this.state.count may not include the updated count immediately after you've set it.
– Tex
Nov 20 '18 at 20:43












I thought the point of the function to set state was that it would make it happen immediately
– David
Nov 20 '18 at 20:45




I thought the point of the function to set state was that it would make it happen immediately
– David
Nov 20 '18 at 20:45












2 Answers
2






active

oldest

votes


















0














Try this incrementItem method:



incrementItem = () => {
this.setState((prevState) => {
const count = prevState.count + 1
return { count, isPrime: this.checkPrime(count) }
})
}


It should work because count is updated immediately and synchronously, then used by this.checkPrime, rather than trying to access this.state.count before it's been updated by setState.






share|improve this answer































    0














    The suggestion was implemented incorrectly. What this article suggested is to use updater function, which is first setState argument. Updater function accepts previous state and current props as parameter and returns new state:



    this.setState((prevState, props) => ({ isPrime: true }));


    Since neither state not props aren't used in new state, there's no need for updater function. If the update was unconditional, it would be just:



    this.setState({ isPrime: true });


    But the purpose of updater function is to prevent race conditions because state updates are asynchronous. This piece will cause race conditions because state.count may be accessed before it was updated:



    this.setState((prevState, { count }) => ({
    count: prevState.count + 1
    }));
    if (this.checkPrime(this.state.count)) {
    ...


    Instead, both state updates should be done with updater functions to keep the order in which they are executed:



    incrementItem = () => {
    this.setState((prevState) => ({
    count: prevState.count + 1
    }));

    this.setState((prevState) => ({
    isPrime: this.checkPrime(prevState.count)
    }));
    }





    share|improve this answer























    • While this is fine, you might as well wrap everything in a single updater function (see my answer).
      – Tex
      Nov 20 '18 at 20:55












    • That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
      – estus
      Nov 20 '18 at 21:21










    • Either answer could be marked as correct. Thank you!!
      – David
      Nov 21 '18 at 19:35











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400937%2freact-set-state-based-on-prime-number-detection%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Try this incrementItem method:



    incrementItem = () => {
    this.setState((prevState) => {
    const count = prevState.count + 1
    return { count, isPrime: this.checkPrime(count) }
    })
    }


    It should work because count is updated immediately and synchronously, then used by this.checkPrime, rather than trying to access this.state.count before it's been updated by setState.






    share|improve this answer




























      0














      Try this incrementItem method:



      incrementItem = () => {
      this.setState((prevState) => {
      const count = prevState.count + 1
      return { count, isPrime: this.checkPrime(count) }
      })
      }


      It should work because count is updated immediately and synchronously, then used by this.checkPrime, rather than trying to access this.state.count before it's been updated by setState.






      share|improve this answer


























        0












        0








        0






        Try this incrementItem method:



        incrementItem = () => {
        this.setState((prevState) => {
        const count = prevState.count + 1
        return { count, isPrime: this.checkPrime(count) }
        })
        }


        It should work because count is updated immediately and synchronously, then used by this.checkPrime, rather than trying to access this.state.count before it's been updated by setState.






        share|improve this answer














        Try this incrementItem method:



        incrementItem = () => {
        this.setState((prevState) => {
        const count = prevState.count + 1
        return { count, isPrime: this.checkPrime(count) }
        })
        }


        It should work because count is updated immediately and synchronously, then used by this.checkPrime, rather than trying to access this.state.count before it's been updated by setState.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 20 '18 at 20:56

























        answered Nov 20 '18 at 20:50









        Tex

        1,6031527




        1,6031527

























            0














            The suggestion was implemented incorrectly. What this article suggested is to use updater function, which is first setState argument. Updater function accepts previous state and current props as parameter and returns new state:



            this.setState((prevState, props) => ({ isPrime: true }));


            Since neither state not props aren't used in new state, there's no need for updater function. If the update was unconditional, it would be just:



            this.setState({ isPrime: true });


            But the purpose of updater function is to prevent race conditions because state updates are asynchronous. This piece will cause race conditions because state.count may be accessed before it was updated:



            this.setState((prevState, { count }) => ({
            count: prevState.count + 1
            }));
            if (this.checkPrime(this.state.count)) {
            ...


            Instead, both state updates should be done with updater functions to keep the order in which they are executed:



            incrementItem = () => {
            this.setState((prevState) => ({
            count: prevState.count + 1
            }));

            this.setState((prevState) => ({
            isPrime: this.checkPrime(prevState.count)
            }));
            }





            share|improve this answer























            • While this is fine, you might as well wrap everything in a single updater function (see my answer).
              – Tex
              Nov 20 '18 at 20:55












            • That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
              – estus
              Nov 20 '18 at 21:21










            • Either answer could be marked as correct. Thank you!!
              – David
              Nov 21 '18 at 19:35
















            0














            The suggestion was implemented incorrectly. What this article suggested is to use updater function, which is first setState argument. Updater function accepts previous state and current props as parameter and returns new state:



            this.setState((prevState, props) => ({ isPrime: true }));


            Since neither state not props aren't used in new state, there's no need for updater function. If the update was unconditional, it would be just:



            this.setState({ isPrime: true });


            But the purpose of updater function is to prevent race conditions because state updates are asynchronous. This piece will cause race conditions because state.count may be accessed before it was updated:



            this.setState((prevState, { count }) => ({
            count: prevState.count + 1
            }));
            if (this.checkPrime(this.state.count)) {
            ...


            Instead, both state updates should be done with updater functions to keep the order in which they are executed:



            incrementItem = () => {
            this.setState((prevState) => ({
            count: prevState.count + 1
            }));

            this.setState((prevState) => ({
            isPrime: this.checkPrime(prevState.count)
            }));
            }





            share|improve this answer























            • While this is fine, you might as well wrap everything in a single updater function (see my answer).
              – Tex
              Nov 20 '18 at 20:55












            • That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
              – estus
              Nov 20 '18 at 21:21










            • Either answer could be marked as correct. Thank you!!
              – David
              Nov 21 '18 at 19:35














            0












            0








            0






            The suggestion was implemented incorrectly. What this article suggested is to use updater function, which is first setState argument. Updater function accepts previous state and current props as parameter and returns new state:



            this.setState((prevState, props) => ({ isPrime: true }));


            Since neither state not props aren't used in new state, there's no need for updater function. If the update was unconditional, it would be just:



            this.setState({ isPrime: true });


            But the purpose of updater function is to prevent race conditions because state updates are asynchronous. This piece will cause race conditions because state.count may be accessed before it was updated:



            this.setState((prevState, { count }) => ({
            count: prevState.count + 1
            }));
            if (this.checkPrime(this.state.count)) {
            ...


            Instead, both state updates should be done with updater functions to keep the order in which they are executed:



            incrementItem = () => {
            this.setState((prevState) => ({
            count: prevState.count + 1
            }));

            this.setState((prevState) => ({
            isPrime: this.checkPrime(prevState.count)
            }));
            }





            share|improve this answer














            The suggestion was implemented incorrectly. What this article suggested is to use updater function, which is first setState argument. Updater function accepts previous state and current props as parameter and returns new state:



            this.setState((prevState, props) => ({ isPrime: true }));


            Since neither state not props aren't used in new state, there's no need for updater function. If the update was unconditional, it would be just:



            this.setState({ isPrime: true });


            But the purpose of updater function is to prevent race conditions because state updates are asynchronous. This piece will cause race conditions because state.count may be accessed before it was updated:



            this.setState((prevState, { count }) => ({
            count: prevState.count + 1
            }));
            if (this.checkPrime(this.state.count)) {
            ...


            Instead, both state updates should be done with updater functions to keep the order in which they are executed:



            incrementItem = () => {
            this.setState((prevState) => ({
            count: prevState.count + 1
            }));

            this.setState((prevState) => ({
            isPrime: this.checkPrime(prevState.count)
            }));
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 '18 at 20:50

























            answered Nov 20 '18 at 20:44









            estus

            67.2k2198213




            67.2k2198213












            • While this is fine, you might as well wrap everything in a single updater function (see my answer).
              – Tex
              Nov 20 '18 at 20:55












            • That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
              – estus
              Nov 20 '18 at 21:21










            • Either answer could be marked as correct. Thank you!!
              – David
              Nov 21 '18 at 19:35


















            • While this is fine, you might as well wrap everything in a single updater function (see my answer).
              – Tex
              Nov 20 '18 at 20:55












            • That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
              – estus
              Nov 20 '18 at 21:21










            • Either answer could be marked as correct. Thank you!!
              – David
              Nov 21 '18 at 19:35
















            While this is fine, you might as well wrap everything in a single updater function (see my answer).
            – Tex
            Nov 20 '18 at 20:55






            While this is fine, you might as well wrap everything in a single updater function (see my answer).
            – Tex
            Nov 20 '18 at 20:55














            That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
            – estus
            Nov 20 '18 at 21:21




            That's true. They can be written this way or another, depending on dev's preferences and a possibility that there may be a need to decouple these updates later.
            – estus
            Nov 20 '18 at 21:21












            Either answer could be marked as correct. Thank you!!
            – David
            Nov 21 '18 at 19:35




            Either answer could be marked as correct. Thank you!!
            – David
            Nov 21 '18 at 19:35


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400937%2freact-set-state-based-on-prime-number-detection%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Fotorealismo