总览

当我们把多个子元素传递给一个只期望有一个React子元素的组件时,会产生"React.Children.only expected to receive single React element child"错误。为了解决该错误,将所有元素包装在一个React片段或一个封闭div中。

这里有个示例来展示错误是如何发生的。

// App.js

import React from 'react';

function Button(props) {
// ️ expects single child element
return React.Children.only(props.children);
} export default function App() {
return (
<Button>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
</Button>
);
}

Button元素期望传递单个子元素,但我们在同级下传递了2个子元素。

React片段

我们可以使用React片段来解决该错误。

import React from 'react';

function Button(props) {
// ️ expects single child element
return React.Children.only(props.children);
} export default function App() {
return (
<Button>
<>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
</>
</Button>
);
}

当我们需要对子节点列表进行分组,而不需要向DOM添加额外的节点时,就会使用Fragments

你可能还会看到使用了更详细的片段语法。

import React from 'react';

function Button(props) {
// ️ expects single child element
return React.Children.only(props.children);
} export default function App() {
return (
<Button>
<React.Fragment>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
</React.Fragment>
</Button>
);
}

上面的两个例子达到了相同的结果--它们对子元素列表进行分组,而没有向DOM中添加额外的节点。

现在大多数代码编辑器都支持更简明的语法,因此更常用。

DOM元素

另一个解决方案是将子元素包裹在另一个DOM元素中,例如一个div

import React from 'react';

function Button(props) {
// ️ expects single child element
return React.Children.only(props.children);
} export default function App() {
return (
<Button>
<div>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
<button
onClick={() => {
console.log('Button clicked');
}}
>
Click
</button>
</div>
</Button>
);
}

这样就解决了错误,因为我们现在向Button组件传递了单一的子元素。

这种方法只有在添加一个额外的div而不会破坏你的布局时才有效,否则就使用一个片段,因为片段不会向DOM添加任何额外的标记。

这是很有必要的,因为Button组件使用React.Children.only函数来验证children属性是否只有一个子元素,并返回它。否则该方法会抛出一个错误。

React.Children.only方法经常被用于第三方库,以确保API的消费者在使用该组件时只提供一个子元素。

React报错之React.Children.only expected to receive single React element child的更多相关文章

  1. react 报错的堆栈处理

    react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...

  2. React报错之Expected `onClick` listener to be a function

    正文从这开始~ 总览 当我们为元素的onClick属性传递一个值,但是该值却不是函数时,会产生"Expected onClick listener to be a function" ...

  3. React报错 :browserHistory doesn't exist in react-router

    由于版本问题,React中history不可用 import { hashHistory } from 'react-router' 首先应该导入react-router-dom包: import { ...

  4. react报错 TypeError: Cannot read property 'setState' of undefined

    代码如下: class test extends Component { constructor(props) { super(props); this.state = { liked: false ...

  5. React报错之Cannot find name

    正文从这开始~ .tsx扩展名 为了在React TypeScript中解决Cannot find name报错,我们需要在使用JSX文件时使用.tsx扩展名,在你的tsconfig.json文件中把 ...

  6. React报错之Cannot find namespace context

    正文从这开始~ 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig. ...

  7. React报错之Functions are not valid as a React child

    正文从这开始~ 总览 产生"Functions are not valid as a React child. This may happen if you return a Compone ...

  8. React报错之Parameter 'props' implicitly has an 'any' type

    正文从这开始~ 总览 当我们没有为函数组件或者类组件的props声明类型,或忘记为React安装类型声明文件时,会产生"Parameter 'props' implicitly has an ...

  9. React报错:Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix,

    今天在开发时报了以下错误,记录一下 我们不能在组件销毁后设置state,防止出现内存泄漏的情况 出现原因直接告诉你了,组件都被销毁了,还设置个锤子的state啊 解决方案: 利用生命周期钩子函数:co ...

  10. react报错this.setState is not a function

    当报错这个的时候就要看函数是否在行内绑定this,或者在constructor中绑定this. 我这里犯的错误的是虽然我在constructor中绑定了this,但是语法写的不正确. 错误示范: co ...

随机推荐

  1. [题解] Atcoder ARC 142 D Deterministic Placing 结论,DP

    题目 (可能有点长,但是请耐心看完,个人认为比官方题解好懂:P) 首先需要注意,对于任意节点i上的一个棋子,如果在一种走法中它走到了节点j,另一种走法中它走到了节点k,那么这两种走法进行完后,棋子占据 ...

  2. P4588 [TJOI2018]数学计算 (线段树)

    用线段树维护操作序列,叶子结点存要乘的数,非叶子结点存区间乘积,每次输出tr[1] 就是答案. 1 #include<bits/stdc++.h> 2 #define ll long lo ...

  3. Vue3解决ElementPlus Drawer或弹出对话框不生效的问题

    第一时间检查你是否还在使用 :visible.sync="drawer" 来绑定事件框的隐藏和显示,vue3.0 已经更改为通过 v-model 来绑定事件框的显示与隐藏.

  4. Dytechlab Cup 2022 (A - C)

    Dytechlab Cup 2022 (A - C) A - Ela Sorting Books 分析:贪心,将字符串每一位都存在map里,从前往后尽量让每一个\(n / k\)的段\(mex\)值尽 ...

  5. 18.MongDB系列之批量更新写入Python版

    在实际的工作中,难免批量更新的数量极大,pymongo提供了便捷的客户端供使用 假设读者对pandas比较熟悉,下图为事先准备好的dataframe import pandas as pd from ...

  6. Nginx通用优化示例

    user nginx; worker_processes auto; #worket_cpu_affinity auto; error_log /var/log/nginx/error.log war ...

  7. 《吐血整理》高级系列教程-吃透Fiddler抓包教程(31)-Fiddler如何抓取Android系统中Flutter应用程序的包

    1.简介 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.Flutter应用程序是用Dart编写的,这是一种由Google在7年多前创建的语言.Flut ...

  8. C# String.IsNullOrEmpty()方法的使用

    IsNullOrEmpty(string)是String类的一个有参的方法,方法需要类的调用,所以String.IsNullOrEmpty(string) IsNullOrEmpty是判断字符串的Nu ...

  9. String基础: String两种创建对象方式的比较

    字符串常量 在一般的语言中常量一旦声明则不可改变,在java中的字符串常量是以匿名对象来表示的 javaz中字符串两种定义方法: String strA= new String("hello ...

  10. javascript异步编程,promise概念

    javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...