Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

微信小程序端是否支持操作jsx数组 #4985

Closed
crimson968 opened this issue Dec 2, 2019 · 17 comments
Closed

微信小程序端是否支持操作jsx数组 #4985

crimson968 opened this issue Dec 2, 2019 · 17 comments
Assignees
Labels
question Further information is requested

Comments

@crimson968
Copy link

crimson968 commented Dec 2, 2019

问题描述

操作jsx数组时,在微信小程序端报错

复现步骤

renderGet(listt){
    const { multi, resultList, userOptionDto } = this.props
    const descType = typeof listt.length === 'number'
    const renderList = <View>{descType && listt.map(item => {
      const {
        optionSeq,
        questionId,
        optionContent
      } = item
      return (
        <View
          key={optionSeq}
          className={this.getCheckedClass(multi, questionId, optionSeq, resultList, userOptionDto)}
          onClick={this.handleChange.bind(this, questionId, optionSeq)}
        >
          {this.getOptionIcon(multi, questionId, optionSeq, resultList)}
          <Text className='option-text'>
            {optionContent}
          </Text>
        </View>
      )
    })}</View>
    console.log(renderList)
    return renderList
  }

只要操作renderList就会报错,console.log一下都会报错

期望行为

在微信小程序端支持操作jsx数组

报错信息

thirdScriptError
renderList is not defined; [Component] Property Observer Error @ pages/my/surveyByQuestionnaire/components/question/question#observer
ReferenceError: renderList is not defined

版本taro-cli 1.3.20

如果您有功能上的建议,可以提到 FeatHub

使用上的问题,欢迎在「Taro 社区」一起交流

@taro-bot
Copy link

taro-bot bot commented Dec 2, 2019

CC @Chen-jj

@taro-bot
Copy link

taro-bot bot commented Dec 2, 2019

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@shenghanqin
Copy link
Collaborator

@crimson968 贴一些页面完整的代码吧?是不是也用了装饰器还是?

@shenghanqin
Copy link
Collaborator

我来说说,不针对这个issue,而只是看着你的源码想到的几个细节

  1. 代码重复,设置图片那里,可以用变量,却在jsx里面写重复的代码
  2. return a && a.map(),这个可能待商量。

还有,可不可以想办法把代码减少,还能复现这个问题?目前这个Demo是有点大的。

@crimson968
Copy link
Author

是说Image的src使用变量吗;我可以删掉一些无关的业务代码

@crimson968
Copy link
Author

crimson968 commented Dec 3, 2019

@shenghanqin 改了个针对此issue的缩减版demo,依旧可以复现该问题,如下:
另外image的src使用变量的写法我之前是有尝试过的,但是不可行,会报错


import Taro, { PureComponent } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './question.scss'

const userOptionDto = {
    'A_TYPE': [
        {
            questionId: '3',
            optionSeq: 'A',
            optionContent: '3A3A3A',
            optionDesc: 'A_TYPE'
        },
        {
            questionId: '3',
            optionSeq: 'B',
            optionContent: '3B3B3B',
            optionDesc: 'A_TYPE'
        },
        {
            questionId: '3',
            optionSeq: 'C',
            optionContent: '3C3C3C',
            optionDesc: 'A_TYPE'
        },
        {
            questionId: '3',
            optionSeq: 'D',
            optionContent: '3D3D3D',
            optionDesc: 'A_TYPE'
        }
    ],
    'B_TYPE': [
        {
            questionId: '3',
            optionSeq: 'E',
            optionContent: '3E3E3E',
            optionDesc: 'B_TYPE'
        },
        {
            questionId: '3',
            optionSeq: 'F',
            optionContent: '3F3F3F',
            optionDesc: 'B_TYPE'
        },
        {
            questionId: '3',
            optionSeq: 'G',
            optionContent: '3G3G3G',
            optionDesc: 'B_TYPE'
        }
    ]
}

class Question extends PureComponent {

    getDescOptions(optionList) {
        const optionType = typeof optionList.length === 'number'
        const viewList = optionType &&
            optionList.map(item => {
                const {
                    optionSeq,
                    optionContent
                } = item
                return (
                    <View
                        key={optionSeq}
                        className='option-view-desc-item'
                    >
                        <Text className='option-text'>
                            {optionContent}
                        </Text>
                    </View>
                )
            })
        console.log(viewList)
        return viewList
    }

    render() {
        return (
            <View className='question-page'>
                {Object.keys(userOptionDto).map(item => {
                    return (
                        <View
                            key={item}
                            className='question-option-desc'
                        >
                            {this.getDescOptions(userOptionDto[item])}
                        </View>
                    )
                })
                }
            </View>
        )
    }
}

export default Question

微信小程序端报错信息:

VM2448:1 thirdScriptError
viewList is not defined; [Component] Lifetime Method Error @ pages/my/surveyByQuestionnaire/components/question/test#attached
ReferenceError: viewList is not defined

@shenghanqin
Copy link
Collaborator

@crimson968 学一下MarkDown语法吧,贴了三次代码,都没有设置代码格式!!!

@crimson968
Copy link
Author

@shenghanqin 好的嘛

@Garfield550
Copy link
Collaborator

建议你写成组件

import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components'

export type DTOItem = {
  questionId: string;
  optionSeq: string;
  optionContent: string;
  optionDesc: string;
}

interface Props {
  optionList: DTOItem[];
}

export default class DTOComponent extends Taro.Component<Props> {
  public render(): JSX.Element {
    const { optionList } = this.props
    return (
      <View>
        {optionList && optionList.map(item => {
          const { optionSeq, optionContent } = item
          return (
            <View
              key={optionSeq}
              className='option-view-desc-item'
            >
              <Text className='option-text'>
                {optionContent}
              </Text>
            </View>
          )
        })}
      </View>
    )
  }
}
import Taro from '@tarojs/taro'
import { View } from '@tarojs/components'
import DTOComponent, { DTOItem } from './component'

type DTOType = {
  [key: string]: DTOItem[]
}

const userOptionDto: DTOType = {
  'A_TYPE': [
    {
      questionId: '3',
      optionSeq: 'A',
      optionContent: '3A3A3A',
      optionDesc: 'A_TYPE'
    },
    {
      questionId: '3',
      optionSeq: 'B',
      optionContent: '3B3B3B',
      optionDesc: 'A_TYPE'
    },
    {
      questionId: '3',
      optionSeq: 'C',
      optionContent: '3C3C3C',
      optionDesc: 'A_TYPE'
    },
    {
      questionId: '3',
      optionSeq: 'D',
      optionContent: '3D3D3D',
      optionDesc: 'A_TYPE'
    }
  ],
  'B_TYPE': [
    {
      questionId: '3',
      optionSeq: 'E',
      optionContent: '3E3E3E',
      optionDesc: 'B_TYPE'
    },
    {
      questionId: '3',
      optionSeq: 'F',
      optionContent: '3F3F3F',
      optionDesc: 'B_TYPE'
    },
    {
      questionId: '3',
      optionSeq: 'G',
      optionContent: '3G3G3G',
      optionDesc: 'B_TYPE'
    }
  ]
}

export default class Index extends Taro.Component {
  public static config: Taro.PageConfig = {
    navigationBarTitleText: '首页'
  }

  public render(): JSX.Element {
    return (
      <View className='question-page'>
        {Object.keys(userOptionDto).map(item => {
          return (
            <View
              key={item}
              className='question-option-desc'
            >
              <DTOComponent optionList={userOptionDto[item]} />
            </View>
          )
        })}
      </View>
    )
  }
}
yarn run v1.19.2
$ taro info
👽 Taro v1.3.26


  Taro CLI 1.3.26 environment info:
    System:
      OS: macOS 10.15.1
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 10.17.0
      Yarn: 1.19.2
      npm: 6.11.3
    npmPackages:
      @tarojs/components: 1.3.26 => 1.3.26 
      @tarojs/components-qa: 1.3.26 => 1.3.26 
      @tarojs/components-rn: 1.3.26 => 1.3.26 
      @tarojs/plugin-babel: 1.3.26 => 1.3.26 
      @tarojs/plugin-csso: 1.3.26 => 1.3.26 
      @tarojs/plugin-sass: 1.3.26 => 1.3.26 
      @tarojs/plugin-uglifyjs: 1.3.26 => 1.3.26 
      @tarojs/rn-runner: 1.3.26 => 1.3.26 
      @tarojs/router: 1.3.26 => 1.3.26 
      @tarojs/taro: 1.3.26 => 1.3.26 
      @tarojs/taro-alipay: 1.3.26 => 1.3.26 
      @tarojs/taro-h5: 1.3.26 => 1.3.26 
      @tarojs/taro-qq: 1.3.26 => 1.3.26 
      @tarojs/taro-quickapp: 1.3.26 => 1.3.26 
      @tarojs/taro-rn: 1.3.26 => 1.3.26 
      @tarojs/taro-router-rn: 1.3.26 => 1.3.26 
      @tarojs/taro-swan: 1.3.26 => 1.3.26 
      @tarojs/taro-tt: 1.3.26 => 1.3.26 
      @tarojs/taro-weapp: 1.3.26 => 1.3.26 
      @tarojs/webpack-runner: 1.3.26 => 1.3.26 
      eslint-config-taro: 1.3.26 => 1.3.26 
      eslint-plugin-taro: 1.3.26 => 1.3.26 
      nerv-devtools: ^1.5.5 => 1.5.6 
      nervjs: ^1.5.5 => 1.5.6 
      stylelint-config-taro-rn: 1.3.26 => 1.3.26 
      stylelint-taro-rn: 1.3.26 => 1.3.26 

✨  Done in 2.55s.

image

@crimson968
Copy link
Author

@Garfield550 主要是需要操作我demo里的viewList数组,根据不同的业务实现不同的布局和样式,组件化的方式我试过了,也是不能操作viewList数组的

@Garfield550
Copy link
Collaborator

你可以在组件的生命周期或者 render() 方法里操作数组,然后只在 return () 语句里进行渲染吗?

export default class DTOComponent extends Taro.Component<Props> {
  // 可否在此操作数组
  public render(): JSX.Element {
    const { optionList } = this.props
    // 又可否在此操作数组
    return ()
  }
}

@Garfield550
Copy link
Collaborator

import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components'

export type DTOItem = {
  questionId: string;
  optionSeq: string;
  optionContent: string;
  optionDesc: string;
}

interface Props {
  optionList: DTOItem[];
}

export default class DTOComponent extends Taro.Component<Props> {
  public render(): JSX.Element {
    const { optionList = [] } = this.props
    const newOptionList = optionList.filter(item => item.optionDesc !== 'B_TYPE')
    return (
      <View>
        {newOptionList.map(item => {
          const { optionSeq, optionContent } = item
          return (
            <View
              key={optionSeq}
              className='option-view-desc-item'
            >
              <Text className='option-text'>
                {optionContent}
              </Text>
            </View>
          )
        })}
      </View>
    )
  }
}

image

@Garfield550
Copy link
Collaborator

import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components'

export type DTOItem = {
  questionId: string;
  optionSeq: string;
  optionContent: string;
  optionDesc: string;
}

interface Props {
  optionList: DTOItem[];
}

interface State {
  demoList: DTOItem[];
}

export default class DTOComponent extends Taro.Component<Props, State> {
  public constructor(props: Props) {
    super(props)
    const { optionList = [] } = this.props
    const demoList = optionList.filter(item => {
      return item.optionContent = `${item.optionContent}-${item.optionDesc}`
    })
    this.state = {
      demoList
    }
  }

  public render(): JSX.Element {
    const { demoList } = this.state
    const newOptionList = demoList.filter(item => item.optionDesc !== 'B_TYPE')
    return (
      <View>
        {newOptionList.map(item => {
          const { optionSeq, optionContent } = item
          return (
            <View
              key={optionSeq}
              className='option-view-desc-item'
            >
              <Text className='option-text'>
                {optionContent}
              </Text>
            </View>
          )
        })}
      </View>
    )
  }
}

image

@Garfield550
Copy link
Collaborator

更改样式也可以这样

{optionContent.includes('TYPE') ? 
  <View className='option-text' style={{ textAlign: 'center' }}>{optionContent}</View> :
  <Text className='option-text'>{optionContent}</Text>
}

image

@crimson968
Copy link
Author

@Garfield550 感谢大佬解答,但是你的demo里子组件获取到的optionList并不是我想操作的数组,那个是json数组,不是jsx数组,我是希望操作我demo的viewList数组的,也就是你子组件render返回的数组,说个实际点的需求吧,我要根据实际业务需求将首次遍历出来的N个View,两两或三三放在同一个(新建的)盒子中,因为要同时操作一行(2-3个View一起修改)的背景色之类的,之前尝试过filter或map该JSX数组,在H5端均正常运行,但是在微信小程序端就会报错了

@Chen-jj
Copy link
Contributor

Chen-jj commented Dec 11, 2019

@Chen-jj Chen-jj added answered question Further information is requested labels Dec 11, 2019
@taro-bot
Copy link

taro-bot bot commented Dec 11, 2019

Hello~

您的问题楼上已经有了确切的回答,如果没有更多的问题这个 issue 将在 15 天后被自动关闭。

如果您在这 15 天中更新更多信息自动关闭的流程会自动取消,如有其他问题也可以发起新的 Issue。

Good luck and happy coding~

@Chen-jj Chen-jj closed this as completed Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants