0

I'm developing a university administration website with React that can be displayed in different languages. So far, I have developed the Login page, please see the code (note that I'm using Babel):

import React from 'react'
import PropTypes from 'prop-types'
import { fetchPopularRepos } from '../utils/api'

function LanguagesNav ({ selected, onUpdateLanguage}) {
  const languages = ['EU', 'ES', 'EN']

  return (
    <div >
      <h1 className='center-text header-lg'>
        GAUR 2.0
      </h1>
      <ul className='flex-center'>
        {languages.map((language) => (
          <li key={language}>
            <button
              className='btn-clear nav-link'
              style={language === selected ? { color: 'rgb(187, 46, 31)' } : null }
              onClick={() => onUpdateLanguage(language)}>
              {language}
            </button>
          </li>
        ))}
      </ul>
    </div>
  )
}

LanguagesNav.propTypes = {
  selected: PropTypes.string.isRequired,
  onUpdateLanguage: PropTypes.func.isRequired
}

function LoginForm ({ repos, selectedLanguage }) {
  return (
    <form className='column player'>
      {console.log(repos)}
      {console.log(selectedLanguage)}

      {(repos, selectedLanguage) => {
        var lang = { username, password, login }

        switch (selectedLanguage) {
          case "EU":
            selectedLanguage = "EU";
            lang  = repos;
            break;
          case "ES":
            selectedLanguage = "ES";
            lang = repos;
            break;
          case "EN":
            selectedLanguage = "EN";
            lang = repos;
            break;
        }

        return (
          <React.Fragment>
            <div className='row player-inputs'>
              <input
                type='text'
                id='username'
                className='input-light'
                placeholder={lang.terms.username}
                autoComplete='off'
              />
            </div>
            <div className='row player-inputs'>
              <input
                type='password'
                id='password'
                className='input-light'
                placeholder={lang.terms.password}
                autoComplete='off'
              />
            </div>
            <div className='row player-inputs'>
              <button
                className='btn dark-btn'
                type='submit'
              >
                {lang.terms.login}
              </button>
            </div>
          </React.Fragment>
        )
      }}
    </form>
  )
}

LoginForm.propTypes = {
  repos: PropTypes.array.isRequired
}

export default class Login extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      selectedLanguage: 'EU',
      repos: null,
      error: null
    }

    this.updateLanguage = this.updateLanguage.bind(this)
    this.isLoading = this.isLoading.bind(this)
  }
  componentDidMount () {
    this.updateLanguage(this.state.selectedLanguage)
  }
  updateLanguage (selectedLanguage) {
    this.setState({
      selectedLanguage,
      error: null,
      repos: null
    })

    fetchPopularRepos(selectedLanguage)
      .then((repos) => this.setState({
          repos,
          error: null,
      }))
      .catch(() => {
        console.warn('Error fetching repos: ', error)

        this.setState({
          error: 'There was an error fetching the repositories.'
        })
      })
  }
  isLoading() {
    return this.state.repos === null && this.state.error === null
  }
  render() {
    const { selectedLanguage, repos, error } = this.state

    return (
      <React.Fragment>
        <LanguagesNav
          selected={selectedLanguage}
          onUpdateLanguage={this.updateLanguage}
        />

        {this.isLoading() && <p>LOADING...</p>}

        {error && <p>{error}</p>}

        {repos != null && <LoginForm repos={repos, selectedLanguage} />}

        {this.state.repos != null && console.log(`${JSON.stringify(repos)}`)}
        {this.state.repos != null && console.log(`${selectedLanguage}`)}

      </React.Fragment>
    )
  }
}

The data is being retrieved from this JSON file:

{
  "languages": [
    {
      "language": "EU",
      "terms": {
        "username": "Erabiltzailea",
        "password": "Pasahitza",
        "welcome": "Sartu GAUR 2.0ra",
        "login": "Sartu"
      }
    },
    {
      "language": "ES",
      "terms": {
        "username": "Usuario",
        "password": "Contraseña",
        "welcome": "Entra a GAUR 2.0",
        "login": "Entrar"
      }
    },
    {
      "language": "EN",
      "terms": {
        "password": "Password",
        "username": "Username",
        "welcome": "Log into GAUR 2.0",
        "login": "Log in"
      }
    }
  ]
}

I'm passing 2 values as props, an array repos and a string selectedLanguage as it can be seen in the console with the console.logs I've included in the code:

render() {
    const { selectedLanguage, repos, error } = this.state

    return (
      <React.Fragment>
        <LanguagesNav
          selected={selectedLanguage}
          onUpdateLanguage={this.updateLanguage}
        />

        {this.isLoading() && <p>LOADING...</p>}

        {error && <p>{error}</p>}

        {repos != null && <LoginForm repos={repos, selectedLanguage} />}

        {this.state.repos != null && console.log(`${JSON.stringify(repos)}`)}
        {this.state.repos != null && console.log(`${selectedLanguage}`)}

      </React.Fragment>
    )
  }

Console:

Value of repos: An array of objects

repos console value before props

Value of selectedLanguage: EU

selectedLanguage console value before props

My problem comes when calling both values in the LoginForm function, the value of repos becomes a single string, and the value of selectedLanguage becomes undefined:

LoginForm

function LoginForm ({ repos, selectedLanguage }) {
  return (
    <form className='column player'>
      {console.log(repos)}
      {console.log(selectedLanguage)}
      {(repos, selectedLanguage) => {
        var lang = { username, password, login }

        switch (selectedLanguage) {
          case "EU":
            selectedLanguage = "EU";
            lang  = repos;
            break;
          case "ES":
            selectedLanguage = "ES";
            lang = repos;
            break;
          case "EN":
            selectedLanguage = "EN";
            lang = repos;
            break;
        }

        return (
          <React.Fragment>
            <div className='row player-inputs'>
              <input
                type='text'
                id='username'
                className='input-light'
                placeholder={lang.terms.username}
                autoComplete='off'
              />
            </div>
            <div className='row player-inputs'>
              <input
                type='password'
                id='password'
                className='input-light'
                placeholder={lang.terms.password}
                autoComplete='off'
              />
            </div>
            <div className='row player-inputs'>
              <button
                className='btn dark-btn'
                type='submit'
              >
                {lang.terms.login}
              </button>
            </div>
          </React.Fragment>
        )
      }}
    </form>
  )
}

Console:

Value of repos: EU

repos console value after props

Value of selectedLanguage: undefined

selectedLanguage console value after props

  • Why are values being converted?
  • How can I pass them without being converted?

1 Answer 1

2

As we can see LoginForm expects 2 props, repos and selectedLanguage

function LoginForm ({ repos, selectedLanguage }) { ... }

But you are passing only repos,

<LoginForm repos={repos, selectedLanguage} />

Here selectedLanguage is getting bind to repos props and you are getting EU in your console, whereas selectedLanguage prop is not being passed and you got undefined.

I am also surprised, why repos={repos, selectedLanguage} is not giving syntax error

You need to separately pass both the values,

<LoginForm repos={repos} selectedLanguage={selectedLanguage} />
Sign up to request clarification or add additional context in comments.

Comments

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.