2

I'm a beginner writing a React app with currently three components minus the root App (yes this is for an online course). The first two don't really matter, but for the third one, named Total, I need to return a sum of the exercises count which are defined as three constants, exercises1~3.

I've been taught how to sum props, but only as {props + props1 + props2...}, and I could do it as well, but it would not be good as the number of parts and exercises grow. I could reduce the values or write a helper function, but React works kinda different and I'm kinda lost as to how I could provide a good scalable solution for this.

//first two components hidden

const Total = (props) => {
    return (
        <>
            <p>help here!!</p>
        </>
    )
}

const App = () => {
    const course = "Half Stack app development"
    const part1 = "Fundamentals of React"
    const exercises1 = 10 //this one
    const part2 = "Using props to pass data"
    const exercises2 = 7 //this one
    const part3 = "State of a component"
    const exercises3 = 14 //and this one

    return (
        <div>
            <Header name={course} />
            <Content name={part1} exercises={exercises1} />
            <Content name={part2} exercises={exercises2} />
            <Content name={part3} exercises={exercises3} />

            <Total exercises= help here!! />
        </div>
    )
}
3
  • in your App component part1, part2, part3 are props coming in? Also exercises1, exercises2, exercises3 Commented Aug 26, 2019 at 19:15
  • Yes, course variable is used for props in Header component, parts are used for props in Content components. exercises1~3 are used for Content and Total. Commented Aug 26, 2019 at 19:24
  • 1
    I meant are they coming in from other components using App component, or is this just an example that you are trying with. Anyway I have posted a custom solution assuming you have full access to your code's data structure Commented Aug 26, 2019 at 19:25

4 Answers 4

2

You should structure your data as an array of objects.

 const exercises = [{ name: 'Fundamentals of React', exercise: 10 }, etc];

in render use

exercises.map(ex => <Content name={ex.name} exercises={ex.exercise}/>)

and for the sum use reduce https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Sign up to request clarification or add additional context in comments.

Comments

2

Here's my solution assuming you control data structure in App component

const Total = (props) => {
    return (
        <>
            <p>props.totalExerciseCount</p>
        </>
    )
}

const App = () => {
    const course: {
      name: "Half Stack app development",
      parts: [
        {
          title: "Fundamentals of React"
          exerciseCount: 10
        },
        {
          title: "Using props to pass data"
          exerciseCount: 7
        },
        {
          title: "State of a component"
          exerciseCount: 14
        },
      ]
    }

  let totalExerciseCount = 0;

    return (
        <div>
            <Header name={course.name} />
            {course.parts.map(part => {
                totalExerciseCount += part.exerciseCount;
                return <Content name={part.title} exercises={part.exerciseCount} />
              })
            }

            <Total exercises={totalExerciseCount} />
        </div>
    )
}

Comments

0

You can create a Total component as a wrapper and count props of children:

const Total = (props) => {
    const { children } = props;
    const total = children.reduce((total, { props }) => total += props.exercises, 0);

    return (
        <>
            {children}
            <p>{total}</p>
        </>
    )
}
const App = () => {
    const course = "Half Stack app development"
    const part1 = "Fundamentals of React"
    const exercises1 = 10 //this one
    const part2 = "Using props to pass data"
    const exercises2 = 7 //this one
    const part3 = "State of a component"
    const exercises3 = 14 //and this one

    return (
        <div>
            <Header name={course} />
            <Total>
              <Content name={part1} exercises={exercises1} />
              <Content name={part2} exercises={exercises2} />
              <Content name={part3} exercises={exercises3} />
            </Total>
        </div>
    )
}
export default App;

3 Comments

And this solution can be scalable
This solution has unnecessary risks associated with it. Any changes to the Content component would break the Total component since it knows too much about its children. It would be better to keep it data oriented with some kind of ContentList which receives the whole data as a prop and renders the children and the total.
@EmileBergeron, yes, I agree with you. One more possible way to make Total component more independent is to pass sumByPropName="exercises" to the Total and use it this way const total = children.reduce((total, { props }) => total += props[sumByPropName], 0)
-1
const Total = (props) => {
    return (<p>{props.exercises}</p>)
}

and then

<Total exercises={exercises1 + exercises2 + exercises3} />

2 Comments

OP says they dont want to do that and trying to avoid
judging by the description (online course), im guessing this is the way theyre supposed to do it and later on they refactor it with state and passing functions to make it more dynamic

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.