道具传递给子组件的问题

Problems with props passed to child component

我无法将 props 传递到我的应用程序中的子组件。

当我导航到具有 <PageTemplate /> 的任何主题 link 时,我得到一个空白页面,并在控制台中显示一条错误消息:主题不可迭代。 subjects 是从另一个文件导入的字符串数组,您可以从下面的代码中看到:-

代码如下:

根组件

import React from "react";

import Signup from './theQuestionsSteps/signup';
import Home from './home';
import ErrorPage from './pageNotFound';
import {
    Mathematics,
    English,
    Physics,
} from './subjects/subjects';

const RouterComponent = () => {

    return (
         <HashRouter>
             <Switch>
                <Route exact path="/" component={Home} />
                <Route path="/signup" component={Signup} />
                <Route path="/maths" component={Mathematics}></Route>
                <Route path="/english" component={English}></Route>
                <Route path="/physics" component={Physics}></Route>
             </switch>
         </HashRouter>
)

export default RouterComponent;

这是我导航到主题组件的页眉组件。导航到没有 <PageTemplate /> 渲染的组件。但是数学抛出了我上面提到的错误。

import {NavLink} from 'react-router-dom';

const HeaderOfCategory = ({subjects}) => {

    const [s1, s2, s3, s4] = subjects;
    const routesVariabele = subjects.map((item) => {
        
        return "/" + item.replace(/\s/, '');
    });

    const [r1, r2, r3, r4] = routesVariabele;
    const styles = { 
        backgroundColor: "green",
        color: "white"
    }

    return (
       <div className="flex flex-row gap-3 w-3/4 mx-auto justify-center">
            <NavLink to={{pathname: r1, subjects}} activeStyle={styles} className="p-3 rounded-lg hover:text-white bg-blue-100 mt-10 hover:bg-green-500 capitalize">{s1}</NavLink>
            <NavLink to={r2} activeStyle={styles} className="p-3 rounded-lg hover:text-white bg-blue-100 mt-10 hover:bg-green-500 capitalize">{s2}</NavLink>
            <NavLink to={r3} activeStyle={styles} className="p-3 rounded-lg hover:text-white bg-blue-100 mt-10 hover:bg-green-500 capitalize">{s3}</NavLink>
            <NavLink to={r4} activeStyle={styles} className="p-3 rounded-lg hover:text-white bg-blue-100 mt-10 hover:bg-green-500 capitalize">{s4}</NavLink>
 </div>

模板组件

import HeaderOfCategory from './headerOfCategory';


const PageTemplate = ({children, subjects}) => 
<div>
    <HeaderOfCategory subjects={subjects} />
    {children}
</div>


export default PageTemplate;

主题组件

import PageTemplate from '../pageTemplate';



export const Mathematics = ({subjects}) => {

     return (
         <PageTemplate subjects={subjects}><div>I am maths</div></PageTemplate>
     )
}

export const English = () => {

     return (
         <div>I am english</div>
     )
}

export const Physics = () => {

     return (
         <div>I am physics</div>
     )
}

用户选择 his/her 主题的主页。这样效果很好。

import React, {useState} from 'react';
import {NavLink} from 'react-router-dom';
import {subjects} from './subjectsList';



const Home = () => {

    const [countSelection, setCountSelection] = useState({four : 0, count : ''});
    const [theInput, setTheInput] = useState([]);

    const handleClick = (e) => {
            setCountSelection({...countSelection, four : countSelection.four + 1});
            if(countSelection.four >= 3){
                setCountSelection({...countSelection, count: 'disabled'});
            }
    }

    const handleChange = (e) => {

        setTheInput([...theInput, e.target.value]);
                    
    }


    return (
        <div className="p-10 w-3/4 mx-auto">
            <div className="p-3 mx-auto">
                <h1 className="text-xl text-gray-500 mx-auto text-center">Select your combination of subjects to begin your exercise</h1>
            </div>
            
    <div  className="flex flex-col w-3/4 mt-8 p-10 mx-auto justify-center shadow-sm shadow-gray-600">
            <p className="mb-5">Note: You can only select Four (4) subjects of your choice</p>
            {subjects.map((item, index) => (
                <div key={index}>
                    <input 
                    type="checkbox" 
                    id={`subject${index}`} value={item} 
                    onChange={handleChange}
                    onClick={handleClick}
                    disabled={countSelection.count}
                    />
                    <label htmlFor="" className="m-5 text-gray-600 capitalize">{item}</label>
                    
                </div>
            
                ))
            }

            {countSelection.count === "disabled" ?<NavLink to={{pathname : "/startPage", theInput}} className="mt-10 w-2/4 p-3 bg-green-500 rounded-lg text-white hover:bg-blue-500 cursor-pointer">Submit</NavLink> : ''}
        </div>

        </div>
    )
}


export default Home;

好的,我想我现在明白了。您正在尝试通过 NavLinksubjects 传递给 Mathematics 组件,即作为路由状态。

<NavLink
  to={{
    pathname: r1,
    subjects, // <-- not a valid to object property
  }}
  activeStyle={styles}
  className="...."
>
  {s1}
</NavLink>

to: object

An object that can have any of the following properties:

  • pathname: A string representing the path to link to.

  • search: A string representation of query parameters.

  • hash: A hash to put in the URL, e.g. #a-hash.

  • state: State to persist to the location.

    <Link
      to={{
        pathname: "/courses",
        search: "?sort=name",
        hash: "#the-hash",
        state: { fromDashboard: true }
      }}
    />
    

这里的问题是 link 不关心任何 subjects 属性。它应该在 state 属性.

上传递
<NavLink
  to={{
    pathname: r1,
    state: { subjects }, // <-- pass in state
  }}
  activeStyle={styles}
  className="...."
>
  {s1}
</NavLink>

由于 Mathematicscomponent 道具上的 Route 直接渲染,因此传递 route props, i.e. history, location, and match. It is in the location 对象,Mathematics 可以访问传递的路由状态.

<Route path="/maths" component={Mathematics} />

...

export const Mathematics = ({ location }) => {
  const { state } = location;
  const { subjects } = state || {}; // provide fallback object to destructure from!

  return (
    <PageTemplate subjects={subjects}>
      <div>I am maths</div>
    </PageTemplate>
  )
}

您可能还想在 PageTemplate 中提供一个默认的 subjects 属性值,这样如果属性没有被传递或者它是未定义的,那么 subjects 至少是一个空的,可迭代的数组。

const PageTemplate = ({ children, subjects = [] }) => (
  <div>
    <HeaderOfCategory subjects={subjects} />
    {children}
  </div>
);