13

I am very noob with reactJs, in fact I just finished this course and am struggling with some concepts here.

I am willing to create an app for people to express their preferences with regards of subjects for a newsletter, and have grabbed a very comprehensive list of topics (2k+) and wanna make some fun way to select them, so I think that something along the lines of Tinder swipeable cards would be a perfect fit, so I am trying to implement this react module functionality into my App.

But it is not showing up anything.

I just created a Repo, in which I had a few tries with no luck.

Basically, the example provided in the module documentation says that it should start by

const data = ['Alexandre', 'Thomas', 'Lucien', 'Raphael', 'Donatello', 'Michelangelo', 'Leonardo']


const Wrapper = () => {
  return (
      <Cards onEnd={console.log("action('end')")} className='master-root'>
        {data.map(item => 
          <Card 
            onSwipeLeft={console.log("action('swipe left')")} 
            onSwipeRight={console.log("action('swipe right')")}>
            <h2>{item}</h2>
          </Card>
        )}
      </Cards>
  )
}

But I am completely lost with it, I supposed that it should provide me with a React Component <Something />, but instead it generate something in the lines of a function, that returns a div, which looks a lot with a component, but I have no idea about how integrate into this example.


Note: In the repo graph, I noticed that there is another developer that made some adjustments to make it compatible with react 16.xx.beta, I'v tried it also, no lucky also.

I am almost sure, that there are some concepts I am missing here, so, any reference is more than welcome, also.

Rafareino
  • 2,515
  • 1
  • 19
  • 26

3 Answers3

10

What you are looking for is a functional stateless component, the below code

const Wrapper = () => {
  return (
    <Cards onEnd={console.log("action('end')")} className='master-root'>
      {data.map(item =>
        <Card
          key={item}
          onSwipeLeft={() => {console.log("action('swipe left')")}}
          onSwipeRight={() => {console.log("action('swipe right')")}}>
          <h2>{item}</h2>
        </Card>
      )}
    </Cards>
  )
}

is a functional component.

According to documentation

Functional and Class Components

The simplest way to define a component is to write a JavaScript function:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “functional” because they are literally JavaScript functions.

The way to render a function component is just like you would render a normal React component

<Wrapper {...props} />  // {...props} is a spread operator syntax to just pass all the props down to wrapper you can pass selected props too

Also react-swipe-card doesn't provide you Wrapper functional component, it provides you components like Cards and Card which you used to render the card view in the Wrapper Component

import Cards, { Card } from 'react-swipe-card' Now in your case it would look like

export default class MyCards extends Component {

  render() {
    return <Wrapper />;
  }
}

However since you don't have a state and also you are not using lifecycle functions you could simple write the above MyCards Component as

export const MyCards= () => {
    return <Wrapper />;
}

I however assume that you would eventually be writing some of the logic there and hence keep it a stateful React component. I have also include the logic whereby you would handle the state change on left or write swipe.

Check a working DEMO

P.S. I a recommendation to go through the React docs thoroughly as they have explained the concepts really well

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Curiously, the example at codesandbox works like a charm on the site, but fails when I download it and build with yarn install; yarn start; The same happens with the other responses too. I am studying a little more as suggested. Thanks – Rafareino Jan 27 '18 at 10:25
  • _By the way_ I am on windows – Rafareino Jan 27 '18 at 10:26
  • @Rafareino, you might check this, when working on windows https://stackoverflow.com/questions/40034690/node-env-is-not-recognised-as-an-internal-or-external-command – Shubham Khatri Jan 27 '18 at 10:41
  • My node server works flawlessly, but this implementation fires a lot of errors. – Rafareino Jan 27 '18 at 14:20
  • @Rafareino, which implementation gives you errors?? and what sort of errors – Shubham Khatri Jan 27 '18 at 16:25
2

If I understand you question as suppose. It look you have some small mistake. I download the repo and run you test on React 15.4.2

Your Card component call:

 <Card 
        onSwipeLeft={console.log("action('swipe left')")} 
        onSwipeRight={console.log("action('swipe right')")}>
        <h2>{item}</h2>
      </Card>

My Card component call:

     <Card 
        key={item}
        onSwipeLeft={()=>{console.log("action('swipe left')")}} 
        onSwipeRight={() => {console.log("action('swipe right')")}}>
        <h2>{item}</h2>
      </Card>

We need to create scope for events handler that is why one of the solution is a arrow function. They aren’t just syntactic sugar around anonymous functions though. An arrow function does not have its own context and will instead use the same this as the context in which it was defined. Here is more detail handle-events-in-react-with-arrow-functions

Also on the MyCards you are returning something like (your code)

export default class MyCards extends Component {

constructor(props) {
super(props);

this.state = {
    
    }
}
render() {
    return Wrapper;
    // return (
    //     <div>
    //         <p>Something</p>
    //         {Wrapper();}
    //     </div>
    // );
}

}

But you should return a component and the way is return it have to be

export default class MyCards extends Component {

constructor(props) {
super(props);

this.state = {        
    }
}
render() {
    return <Wrapper/>      
}

}

Suggestion: If you are not going to have any state in the MyCards component you can make it a functional Component

Community
  • 1
  • 1
Angel
  • 1,670
  • 1
  • 11
  • 14
0

The current top answer is correct and great about the concept of the functional component. You are actually creating a High Order Component.

However I feel your repo can actually be fixed by just making this change:

render() {
        return Wrapper();
    }

See that I actually executed the Wrapper function in order to get the Component as a result, otherwise you are rendering a function and not a Component.

You can refactor your code to actually extend a React.Component, and I actually recommend this as HOC are better used for another type of objective, like decorators.

See here, the only thing I changed is that: https://codesandbox.io/s/xp6pzpyoq

sebastianf182
  • 9,844
  • 3
  • 34
  • 66
  • Curiously, the example at codesandbox works like a charm on the site, but fails when I download it and build with yarn install; yarn start. – Rafareino Jan 27 '18 at 10:26
  • _By the way_ I am on windows – Rafareino Jan 27 '18 at 10:26
  • Keep in mind a did a minor variation from the other answer. I had to change, for example that the styles imported were style instead of styles. Maybe there is another minor change you need to do but basically your code was fine. You just missed executing the function so the component is rendered instead of the function. – sebastianf182 Jan 28 '18 at 04:04