Javascript 如何正确包装JSX元素并根据选择显示JSON

Javascript 如何正确包装JSX元素并根据选择显示JSON,javascript,json,reactjs,jsx,babeljs,Javascript,Json,Reactjs,Jsx,Babeljs,我正在开发一个大学管理网站,可以用不同的语言显示React。到目前为止,我已经开发了如下的登录页面: 此时,我正试图用所选语言eu、ES、EN显示网站,但出现模块构建失败错误: 我真的不明白为什么会出现这个错误,因为我认为JSX/html标记包装正确。注意,我使用的是Babel,请参阅代码: Login.js 使用api: api.js 错误的真正原因是什么 根据React的选择,显示JSON数据的正确方式是什么 将渲染中返回的内容包装到标记中 这就像错误消息所说的:相邻的标记必须包装在[par

我正在开发一个大学管理网站,可以用不同的语言显示React。到目前为止,我已经开发了如下的登录页面:

此时,我正试图用所选语言eu、ES、EN显示网站,但出现模块构建失败错误:

我真的不明白为什么会出现这个错误,因为我认为JSX/html标记包装正确。注意,我使用的是Babel,请参阅代码:

Login.js

使用api:

api.js

错误的真正原因是什么

根据React的选择,显示JSON数据的正确方式是什么


将渲染中返回的内容包装到标记中


这就像错误消息所说的:相邻的标记必须包装在[parent]标记中。

函数必须返回单个DOM元素或片段

更深入地了解一下你在这里返回的内容

函数LoginForm{repos,selectedLanguage}{ //... 回来 {lang.login} }} //...
您可以将所有内容包装到另一个元素中,也可以使用或。

错误就是因为这样

return (
  <div className='row player-inputs'>
    <input
      type='text'
      id='username'
      className='input-light'
      placeholder={lang.username}
      autoComplete='off'
    />
  </div>
  <div className='row player-inputs'>
    <input
      type='password'
      id='password'
      className='input-light'
      placeholder={lang.password}
      autoComplete='off'
    />
  </div>
  <div className='row player-inputs'>
    <button
      className='btn dark-btn'
      type='submit'
    >
      {lang.login}
    </button>
  </div>
)
此处出现错误:

return (
 <div className='row player-inputs'>
        <input
          type='text'
          id='username'
          className='input-light'
          placeholder={lang.username}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <input
          type='password'
          id='password'
          className='input-light'
          placeholder={lang.password}
          autoComplete='off'
        />
      </div>
      ...
您应该将其包装为一个标签,如

例如:

    return (
<div>
      <div className='row player-inputs'>
        <input
          type='text'
          id='username'
          className='input-light'
          placeholder={lang.username}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <input
          type='password'
          id='password'
          className='input-light'
          placeholder={lang.password}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <button
          className='btn dark-btn'
          type='submit'
        >
          {lang.login}
        </button>
      </div>
</div>
    )
错误的真正原因是什么

组件正在返回多个JSX元素。但不包含在单个父JSX元素中。因此,按照错误提示使用

return (
  <> // shorthand syntax of React.Fragment
    {children}
  </>
);
根据React的选择,显示JSON数据的正确方式是什么

据我所知,您正确地跟踪了React的状态


状态即selectedLanguage存储在父组件中并传递给

我使您的代码按预期工作,请运行并让我知道您的反馈

变化

包装的元素返回React.Fragment getSelectedLang引入了新方法来处理selectedLang,而不是在LoginForm中 LoginForm已更改为类内的成员 直接注入响应,而不是请求获取数据 见守则-


我自己设法解决了这个问题。我没有正确地传递道具,因为我试图在LoginForm函数中接收2个道具,而我只传递了1个,并且没有检查repos是否为null:

<LoginForm repos={repos, selectedLanguage} />
解决方案:

{repos && <LoginForm repos={repos} selectedLanguage={selectedLanguage} />}
我设法解决了这个问题,问了另一个问题:

然后我在LoginForm函数中开发了一个逻辑,以显示所选的语言

完整解决方案:


谢谢你的回答。我认为你的答案是正确的,但是,我认为最好像其他答案所建议的那样用标签来包装它。是的,你是对的。这确实是比我的解决方案更好的解决方案,因为它不需要为回答我的第一个问题添加多余的感谢。关于第二个问题的答案,如果我错了请纠正我,但我认为映射对我想做的不起作用,因为我需要通过所选语言和基于选定语言JSON项目。谢谢您的回答,但是,即使您的解决方案可能起作用,我也不认为它是有效的。当您将整个代码解构并将JSON数据放在一个对象中时。请看我的答案,因为我已经设法开发出一个解决方案,在保持代码良好的同时满足我的要求。谢谢你的反馈谢谢你的评论,但问题已经解决了。
return (
 <div className='row player-inputs'>
        <input
          type='text'
          id='username'
          className='input-light'
          placeholder={lang.username}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <input
          type='password'
          id='password'
          className='input-light'
          placeholder={lang.password}
          autoComplete='off'
        />
      </div>
      ...
    return (
<div>
      <div className='row player-inputs'>
        <input
          type='text'
          id='username'
          className='input-light'
          placeholder={lang.username}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <input
          type='password'
          id='password'
          className='input-light'
          placeholder={lang.password}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <button
          className='btn dark-btn'
          type='submit'
        >
          {lang.login}
        </button>
      </div>
</div>
    )
return (
  <> // shorthand syntax of React.Fragment
    {children}
  </>
);
import ReactDOM from "react-dom";
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
};



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);
    this.LoginForm = this.LoginForm.bind(this);
  }
  getSelectedLang  = (repos, selectedLanguage) => {

        console.log('repos', repos);
          console.log('selectedLanguage', selectedLanguage);
        var lang = "";
        switch (selectedLanguage) {
          case "EU":
            selectedLanguage = "EU";
            lang = repos && repos[0];
            break;
          case "ES":
            selectedLanguage = "ES";
            lang = repos && repos[1];
            break;
          case "EN":
            selectedLanguage = "EN";
            lang = repos && repos[2];
            break; 
            default: 
            break;
        }

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

  }
  LoginForm = (repos, selectedLanguage) => {
   // let { repos, selectedLanguage } = data;

  return (
    <form className="column player">
      {this.getSelectedLang(repos, selectedLanguage)}
    </form>
  );
}
  componentDidMount() {
    this.updateLanguage(this.state.selectedLanguage);
   // console.log("heoocds");
  }
  updateLanguage = (selectedLanguage) => {
    //console.log(selectedLanguage);
   // console.log("heoocds");

    let obj = 
        [{
          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"
          }
        } ]
        this.setState({
          selectedLanguage,
          error: null,
          repos: obj
        });
    };


    // 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;
    // console.log(repos);
    // console.log(selectedLanguage)
    return (
      <React.Fragment>
        <LanguagesNav
          selected={selectedLanguage}
          onUpdateLanguage={this.updateLanguage}
        />
        {this.isLoading() && <p>LOADING...</p>}
        {error && <p>{error}</p>}
        {this.LoginForm(repos, selectedLanguage)}

      </React.Fragment>
    );
  }
}

ReactDOM.render(<Login />, document.getElementById("root"));
<LoginForm repos={repos, selectedLanguage} />
{repos && <LoginForm repos={repos} selectedLanguage={selectedLanguage} />}
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 }) {
  var lang = {}
  switch (selectedLanguage) {
    case "EU":
      selectedLanguage = "EU";
      lang  = repos[0].terms;
      break;
    case "ES":
      selectedLanguage = "ES";
      lang = repos[1].terms;
      break;
    case "EN":
      selectedLanguage = "EN";
      lang = repos[2].terms;
      break;
  }

  return (
    <form className='column player'>
      <div className='row player-inputs'>
        <input
          type='text'
          id='username'
          className='input-light'
          placeholder={lang.username}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <input
          type='password'
          id='password'
          className='input-light'
          placeholder={lang.password}
          autoComplete='off'
        />
      </div>
      <div className='row player-inputs'>
        <button
          className='btn dark-btn'
          type='submit'
        >
          {lang.login}
        </button>
      </div>
    </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 && <LoginForm repos={repos} selectedLanguage={selectedLanguage} />}

      </React.Fragment>
    )
  }
}