React Redux for Beginners(part_6)

part1 & part2 & part3 & part4 & part5

Sanje Qi
3 min readOct 20, 2019

Before we move on to archive a story let’s take a look at how to transfer and consuming props.

Transferring Props

It’s a common pattern in React to wrap a component in an abstraction. The outer component exposes a simple property to do something that might have more complex implementation details.

<Component {...this.props} more="values" />

If you don’t use JSX, you can use any object helper such as ES6 Object.assign or Underscore _.extend:

React.createElement(Component, Object.assign({}, this.props, { more: 'values' }))

Consuming and Transferring the Same Prop

If your component wants to consume a property but also wants to pass it along, you can repass it explicitly with checked={checked}. This is preferable to passing the full props object since it's easier to refactor and lint.

function FancyCheckbox(props) {
var { checked, title, ...other } = props;
var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';
var fancyTitle = checked ? 'X ' + title : 'O ' + title;
return (
<label>
<input {...other}
checked={checked}
className={fancyClass}
type="checkbox"
/>
{fancyTitle}
</label>
);
}

ARCHIVE A STORY

Now you will add your first feature: archiving a story. Therefore you will have to introduce Redux at some point to your application to manage the state of archived stories in your application. I want to highly emphasize that it would work in basic React too. But for the sake of learning Redux, you will already use it for this feature. In this section, you will not introduce Redux though.

First, an archiving function can be passed down to the Story component from your src/index.js file. In the beginning, it can be an empty function. The function will be replaced later when you will dispatch a Redux action.

...ReactDOM.render(<App stories={stories} onArchive={() => {}} />,document.getElementById('root'));

Second, you can pass it through your App and Stories components. These components don’t use the function but only pass it to the Story component. You might already notice that this could be a potential refactoring later on, because the function gets passed from the above through all components to only reach the last component. It passes the App component:

const App = ({ stories, onArchive }) =><div className="app"><Storiesstories={stories}onArchive={onArchive}/></div>

And it passes the Stories component:

const Stories = ({ stories, onArchive }) =><div className="stories"><StoriesHeader columns={COLUMNS} />{(stories || []).map(story =><Storykey={story.objectID}story={story}columns={COLUMNS}onArchive={onArchive}/>)}</div>

Finally, you can use it in your Story component in a onClick handler of a button. The story objectID will be passed in the handler to identify the story that is going to be archived.

const Story = ({ story, columns, onArchive }) => {const {title,url,author,num_comments,points,objectID,} = story;return (<div className="story">...<span style={{ width: columns.archive.width }}><buttontype="button"className="button-inline"onClick={() => onArchive(objectID)}>Archive</button></span></div>);}

A refactoring that you could already do would be to extract the button as a reusable component:

const Story = ({ story, columns, onArchive }) => {...return (<div className="story">...<span style={{ width: columns.archive.width }}><ButtonInline onClick={() => onArchive(objectID)}>Archive</ButtonInline></span></div>);}const ButtonInline = ({onClick,type = 'button',children}) =><buttontype={type}className="button-inline"onClick={onClick}>{children}</button>

You can make even another more abstract Button component in the src/components/Story.js file that doesn't share the button-inline CSS class.

...const ButtonInline = ({onClick,type = 'button',children}) =><Buttontype={type}className="button-inline"onClick={onClick}>{children}</Button>const Button = ({onClick,className,type = 'button',children}) =><buttontype={type}className={className}onClick={onClick}>{children}</button>

Both button components should be extracted to a new file called src/components/Button.js but exported so that at least the ButtonInline component can be reused in the Story component. Now, when you start your application again, the button to archive a story is there. But it doesn't work because it only receives a no-op (empty function) as property from your React entry point. Later you will introduce a Redux action that can be dispatched from this function to archive a story. Part 7 next week. Thank you

Source: StackOverflow, Robin Wieruch, Medium, ReactJs, MDN, bitsrc

--

--