前言
当前项目组用的 版本是Taro v2.2.16
多层嵌套循环的数据解构时取值有问题
栗子:
import Taro from '@tarojs/taro';
import { View } from '@tarojs/components';
class A extends Taro.Component {
data = [
{
title: '项目1',
type: 1,
children: [{ title: '项目1-1' }, { title: '项目1-2' }],
},
{
title: '项目2',
type: 2,
children: [{ title: '项目2-1' }, { title: '项目2-2' }],
},
];
render() {
return (
<View>
{this.data.map((outItem) => {
const { title, type, children } = outItem;
return (
<View>
<View>{title}</View>
<View>
{children.map((innerItem) => {
console.log(type); // 问题点所在,会打印出undefined
return (
<View>
{type === 1 && <View>{innerItem.title} - 类型一</View>}
{type === 2 && (
<View>{innerItem.title} - 这是一个类型二</View>
)}
</View>
);
})}
</View>
</View>
);
})}
</View>
);
}
}
export default A;
复制代码
现象:
上面的console.log理应正常打印出type的值,但是Taro编译后,会打印出undefined。显而易见,下面的条件判断全部都会是false,从而出错。
- 原因:
查看编译后的代码发现,Taro会对map中的代码进行编译,编译结果大致如下
var loopArray128 = data.map(function (outItem) {
var outItem = {
$original: (0, _index.internal_get_original)(outItem)
}
var _outItem$$original = outItem.$original,
title = _outItem$$original.title,
type = _outItem$$original.type,
children = _outItem$$original.children;
var $anonymousCallee__36 = children.map(function (innerItem) {
innerItem = {
$original: (0, _index.internal_get_original)(innerItem)
};
console.log(outItem.type); // 最后会编译成这样 outItem.type就不能取到想要的值了
// ... other code
});
}
复制代码
解决方案:
不要使用解构,以下是部分代码
render() {
return (
<View>
{this.data.map((outItem) => {
const { title, children } = outItem;
return (
<View>
<View>{title}</View>
<View>
{children.map((innerItem) => {
console.log(outItem.type); // 此时会编译成outItem.$original.type 值正常打印
return (
<View>
{type === 1 && <View>{innerItem.title} - 类型一</View>}
{type === 2 && (
<View>{innerItem.title} - 这是一个类型二</View>
)}
</View>
);
})}
</View>
</View>
);
})}
</View>
);
}
复制代码
props和state使用同样的变量名
栗子:
class Demo {
state = {
operationKeys: []
}
render() {
const { operationKeys } = this.props
console.log('operationKeys', operationKeys, operationKeys.length > 0)
return (
<View>
{operationKeys.length > 0 ? (
<View>has data</View>
) : (
<NoData/>
)}
</View>
)
}
}
复制代码
现象:
组件在 props.operationKeys.length > 0 为true时,始终渲染
原因:
Taro在编译 tsx(或jsx) 时,会将 js 逻辑和模板分离,js部分逻辑会根据 jsx 中的分支判断,生成一个 data,用于给模板进行渲染。jsx 中的标签部分会编译成wxml。如果props和state用了同样的变量名,并且state不更新,会导致渲染的时候一直使用state下的该变量,使得渲染错误。
JSX中三元表达式的嵌套也可能有问题(神奇的Taro)
栗子:
{isSomething ? (
<View className="row">
<View className="row-title">栗子</View>
<View className="row-content">
{Boolean(tampArrayList)
? tampArrayList.map((item, i) => (
<View key={item.id + `${i}`}>
{`${item.name}*${item.num},${item.content}`}
</View>
))
: '-'}
</View>
</View>
) : null}
复制代码
现象:
taro将代码编译的风马牛不相及,导致出现了不可预料的错误
// 编译给wxml用的变量
var anonymousState__temp5 = Boolean(tampArrayList);
// 这里不知道为什么省去了Boolean(tampArrayList)的表达式
// 导致tampArrayList.map报了Error
var loopArray197 = isWeddingPhoto ? tampArrayList.map(function (item, i) {
item = {
$original: (0, _index.internal_get_original)(item)
};
// 这里又神奇的出现了Boolean(tampArrayList)的表达式
// $loopState__temp3为wxml使用的key值,根本与anyArrayList的状态无关
var $loopState__temp3 = Boolean(anyArrayList) ? item.$original.id + ("" + i) : null;
return {
$loopState__temp3: $loopState__temp3,
$original: item.$original
};
}) : [];
复制代码
原因:
Taro太辣鸡
解决:
把里面的三元表达式赋值给一个变量
render() {
const productList = Boolean(tampArrayList)
? tampArrayList.map((item, i) => (
<View key={item.id + `${i}`}>
{`${item.name}*${item.num},${item.content}`}
</View>
))
: '-';
// ...
return (
<View className="row-content">{productList}</View>
)
}
复制代码
还有一些 还没找到原因 但凭借踩坑经验 却顺利解决了的
scroll-view使用flex布局,可能出现无效的情况(神奇的小程序)
自定义组件内传入组件作为节点渲染出错
栗子:
import Taro from '@tarojs/taro';
import { View, Input } from '@tarojs/components';
// Cell是一个自定义组件,title是标题,renderContent传入DOM用于渲染内容
import { Cell } from '@components/index';
class A extends Taro.Component {
data = [
{
title: '标题一',
content: '输入的内容111',
},
{
title: '标题二',
content: '输入的内容222',
},
];
render() {
return (
<View>
{this.data.map((item) => {
const { title, content } = item;
return (
<Cell
title={title}
renderContent={<Input placeholder="请输入" value={content} />}
/>
);
})}
</View>
);
}
}
复制代码
现象:
Input的value值没有按照预想的显示出来。但content确有其值。
原因
待确定
解决方案:
只需要在最外层包裹一个View即可解决这个问题。
<Cell
title={title}
renderContent={
<View>
<Input placeholder="请输入" value={content} />
</View>
}
/>
复制代码
解构store中的方法后传入自定义组件编译报错
import Taro from '@tarojs/taro';
import { View, Input } from '@tarojs/components';
// Cell是一个自定义组件,onClick是一个自定义的点击事件
import { Cell } from '@components/index';
// Store是用于存储数据的类(mobx)
import Store from './store';
class A extends Taro.Component {
store = new Store();
render() {
const { name, handleClick } = this.store;
return (
<View>
<View onClick={handleClick}>{name}</View>
<Cell onClick={handleClick} />
</View>
);
}
}
export default A;
复制代码
现象
自定义组件Cell传入自定义方法之后,编译会出问题。但是View似乎就没有问题。
原因
待确定
解决
直接传入方法,或者使用匿名函数包裹。以下是部分代码:
<Cell onClick={() => handleClick()} />
// or
<Cell onClick={this.store.handleClick} />
复制代码
总结
-
以上问题 有些Taro3中已经解决 但Taro 依旧有些坑,当我的迭代任务工作中百思不得其解的时候 就会在出问题的那个jsx 元素外层再包一层
<View>
这是一个偷懒行为。但真的很管用 -
其次:遇到问题的时候可以先再去过一遍Taro的最佳实践
最后如果觉得本文有帮助 记得点赞三连哦 十分感谢
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END