【问题标题】:Simplified style change onPress React Native简化样式更改 onPress React Native
【发布时间】:2020-06-10 08:39:23
【问题描述】:

以下是学习在 react native 中简单地更改元素 onPress 的样式的第一次尝试。精通网络语言我觉得很难,因为它不是那么简单。

由于未知原因,该元素需要单击两次才能执行。

export class NavTabItem extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            active: false
        }
        this.NavTabAction = this.NavTabAction.bind(this)
    }

    NavTabAction = (elem) => {
        elem.setState({active: !elem.state.active})
    }

    render() {
        return (
            <TouchableOpacity
            style={this.state.active ? styles.NavTabItemSelected : styles.NavTabItem}
            onPress={()=> {
                this.NavTabAction(this)
            }}>
                <View style={styles.NavTabIcon} />
                <Text style={styles.NavTabLabel}>{this.props.children}</Text>
            </TouchableOpacity>
     );
  }
}

其他问题:

我还没有弄清楚如何在单击时将父级下的其他元素的活动状态设置为 false。

另外,有没有一种简单的方法来影响子元素的样式,就像 web.xml 一样。目前我看不到父样式通过选择器影响子元素的方法,就像你可以使用 CSS 一样

例如。一个样式表,上面写着NavTabItemSelected Text :{ // active style for &lt;Text&gt; }

【问题讨论】:

  • 明确什么需要点击两次。预期的结果是什么?元素不执行。第一次和第二次点击会调用哪些函数?
  • @Max 任何点击都会触发 NavTabAction 函数,但是在第二次点击之前状态不会改变。
  • 是否需要点击 2 次?你能准备一份世博小吃看看吗?
  • setState 是异步的reactjs.org/docs/react-component.html#setstate 这就是为什么我在渲染@RobinKnight 中专门询问console.logs
  • 根据提供的代码,如果 this.state.active 是真实的,它应该应用样式。NavTabItemSelected 样式,所以我会说检查你的样式.. 我从来没有负责三元运算符不工作跨度>

标签: react-native styles onpress


【解决方案1】:

不应调用elem.setStateelem.state,而应调用this.setStateelem.state

NavTabAction = (elem) => {
    this.setState(prev => ({...prev, active: !prev.active}))
}

而不是在onPress 中传递this,您应该只传递函数的引用。

onPress={this.NavTabAction}>

您还应该删除此行,因为您正在使用箭头功能

// no need to bind when using arrow functions
this.NavTabAction = this.NavTabAction.bind(this)

另外,有没有一种简单的方法可以像web一样影响子元素的样式

您可以查看styled-component,但我认为该功能尚不存在用于 react native。你应该做的是将 props 传递给子组件。

【讨论】:

  • 谢谢,但仍然需要点击两次。
  • 拥有单独的样式表并有条件地请求状态并正确设置此状态应该会触发屏幕/或发生更改的元素的重新渲染。
  • @yesIamFaded 确实如此,但仅在第二次点击每个元素时
  • @RobinKnight 那么我猜它是你的 onPress 函数中的一个错误尝试向它添加一个 console.log 并查看它是否在第一次点击时触发。您也可以尝试将 onPress 设置为:` onPress={()=> this.setState({ active: !this.state.active }) ` 或类似的东西
  • @yesIamFaded 相同的行为,控制台在第一次点击时将状态显示为 false。
【解决方案2】:

感谢大家对此的帮助,并用代码整理了一些其他的点点滴滴。

然而,问题在于样式在第二次点击时发生了变化。几个小时后,我为任何遭受此痛苦的人找到了原因和解决方案。如果任何回答过这个问题的更有经验的人认为这个答案不正确或者他们有更好的答案,请发布它,但目前这是我找到的唯一解决方法。

原因:

使用 setState 可以正确地重新渲染变量。这既可以通过 console.log() 在控制台中看到,也可以直接在渲染中输出,使它们可见。

但是,无论怎么尝试,这都没有更新样式。无论是样式表中的样式名称还是内联样式,它们都会在第二次单击而不是第一次单击时更新,但仍会更新为第一次单击的参数。因此,如果第一次单击应该使按钮从红色变为绿色,即使新状态已呈现,它也不会这样做。但是,如果随后的单击应将按钮变回红色,则该按钮现在将变为绿色(就像第一次单击时应该具有的那样)。然后它会在第三次点击时变红,似乎总是比传递给它的状态晚一步。

解决方案

要解决此问题,请取消主要元素的样式(请原谅术语,有人编辑),在我的例子中,是 TouchableOpacity 元素。添加一个子 View 元素并将样式与三元运算符和 wallah 一起放置在该 View 元素上。

如果您愿意,似乎对有效主元素或容器的状态有任何更改,仅在另一次渲染后生效,而不是包含在 setStatus 中。

最终代码:

export class NavTabItem extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            active: false
        }
    }

    NavTabAction = () => {
        this.setState({active: !this.state.active})
    }

    render() {
        this.state.active == true ? console.log("selected") : console.log("unselected")
        return (
            <TouchableOpacity onPress={this.NavTabAction}>

              // added View containing style and ternary operator

                <View style={this.state.active == true ? styles.NavTabItemSelected : styles.NavTabItem}>
                    <View style={styles.NavTabIcon} />
                    <TextCap11 style={styles.NavTabLabel}>{this.props.children}</TextCap11>
                </View>

              // End added view

            </TouchableOpacity>
     );
  }
}

【讨论】:

  • 我从未体验过您描述的效果(元素应用错误的样式,因为它们是其他元素的包装器)。当然应该可以在包装元素上使用样式而不创建额外的子元素。我相信最小的可重现示例是正确剖析问题的唯一方法
  • @Max 有时间我会准备点心。
猜你喜欢
  • 2018-03-18
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
相关资源
最近更新 更多