當前項目組用的 版本是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,從而出錯。markdown
查看編譯後的代碼發現,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
});
}
複製代碼
不要使用解構,如下是部分代碼oop
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>
);
}
複製代碼
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下的該變量,使得渲染錯誤。flex
{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將代碼編譯的風馬牛不相及,致使出現了不可預料的錯誤this
// 編譯給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太辣雞spa
把裏面的三元表達式賦值給一個變量code
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>
)
}
複製代碼
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確有其值。component
待肯定
只須要在最外層包裹一個View便可解決這個問題。
<Cell
title={title}
renderContent={
<View>
<Input placeholder="請輸入" value={content} />
</View>
}
/>
複製代碼
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的最佳實踐
最後若是以爲本文有幫助 記得點贊三連哦 十分感謝