skip to Main Content

I’m discovering React and I think there’s something I don’t understand correctly. Where am I supposed to put the code which computes things before displaying them, what would be the Model in a traditional MVC? Let’s say my app deals with fruits, and I want to display a list of them. So I get the list from an API (something like [{type: banana, boughtDate: 2021-01-03}, {type: apple, boughtDate: 2021-01-02}], give it to a FruitsList component, which loops over and generate FruitRow components. Now, I want to display every rows which are a banana in yellow. I can add a style="color: yellow" in my row component with a condition on the fruit type. But what if I want to have this color in every places where a banana is displayed in my app? That would duplicate this kind of if in every components. What is the React solution to this?

I could have an “utils” file with a function which takes a fruit and return the color, I guess, but that sounds like a very 2005 way of coding. Where I’m confused is that, in Java or other object languages where I come from, I would have a getColor() method on the Fruit class, and the Banana subclass would override it to return yellow. Or at the very least I would have the if (type === "banana") only once, in the getColor method of Fruit class. Can I (and should I) try to recreate that model in React with Javascript classes? So my ¨logical" code is only in one place, and then I could have generic component like Row which would take content and color as props, instead of a Fruit? If yes, where should I put this code?

Edit: Searching on the web, the official React doc links to this presentation by Pete Hunt from Facebook in 2013, where he says: "only put display logic in your components, I’m not advocating putting all your model validation code and fetching and data access in components, you might want to put them in third-party libraries that have some sort of bridges to your components, but only put logic that makes sense in your components"

So I think this is what I’m talking about, are there good practices about those "bridges", where do you put this logic?

2

Answers


  1. I could have an “utils” file with a function which takes a fruit and return the color, I guess, but that sounds like a very 2005 way of coding.

    Absolutely not at all! One of the things that makes react so strong is that it plays well with existing accepted practices and gives you options. Lets look at the issue you described and see what solutions we might be able to come up with.

    Now, I want to display every rows which are a banana in yellow. I can add a style="color: yellow" in my row component with a condition on the fruit type.

    So an important distinction to make here is, do you only want to style the row, or do you want to style "bananna" everywhere?

    But what if I want to have this color in every places where a banana is displayed in my app? That would duplicate this kind of if in every components.


    OPTION 1

    In that case you COULD create a <Bananna /> component (and for each other fruit) and render that, which means you only need to style that one component and changing it in one place will affect all others.


    OPTION 2

    Use the method you descibed and just have it in a helper/utils file. I’ve been working on react applications since mid 2016 and I STILL find use for having separate files with re-usable logic in them.


    OPTION 3

    Your second option could be to use css module for this approach, using css modules would allow you to do something like css[bananna] in your component and which would apply the styling and prevent the need for you to have a switch statement.

    Login or Signup to reply.
  2. Do this where you want to render anything that happens to have type: banana

    <BananaType>
        <WhateverYouWantToPutHere/>
    </BananaType
    

    And define BananaType like this:

    const BananaType = props => <div style="color: yellow">{props.children}</div>
    

    You can add logic to the BananaType component (e.g. fetch a thumbnail from an API) as well. Just do something like this:

    const BananaType = props => {
        const fetched_stuff = someHandyFunctionForFetchingStuff();
    
        return <div><div>{fetched_stuff}</div>{props.children}</div>
    }
    

    If you only want to do some logic, and don’t want to change the DOM at all, do this:

    const BananaType = props => {
        // Do whatever stuff you want to do here
    
        return props.children;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search