Page 1 of 1

RN Popup.custom自定义View中Slider滑动后无法更新到Text组件

Posted: 2025年 Jul 13日 16:55
by feige2023

由于是旧项目,需要维护,所以暂时还没有迁移到小程序
设计目标,在弹窗页面中,通过滑动条和TouchOpacity来修改testValue,并通过Text显示

测试结果发现:拖动滑条后通过加减,Text的组件均不会发生改变,通过日志是可以发现testValue的值有修改成功的

Code: Select all

/* 以下是代码示例片段 */
_popupView=()=>{
const {testValue}=this.state;
const ActiveThemeColor = '#0277ED';
Popup.custom({
title:"测试",
content:(
<View style={{width:'100%',height:cx(320),backgroundColor:'#ffffff',borderRadius:cx(10),padding:cx(20),display:'flex',flexDirection:'column'}}>
<View style={{width:'100%',height:cx(60),display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center'}}>
<Text style={{fontSize:12,color:'#3B4051',height:cx(15)}}>{(testValue-100)/10}%</Text>
<View style={{width:'100%',height:cx(40),display:'flex',flexDirection:'row',alignItems:'center',justifyContent:'space-between',marginBottom:cx(10)}}
onPress={()=>{
let value = testValue-10;
if(value<0){
value=0;
}
this.setState({
testValue:value
})
}}
>
<TouchableOpacity style={{width:'5%',backgroundColor:ActiveFontColor,justifyContent:'center',alignItems:'center',borderRadius:cx(6)}}>
<Text style={{color:'white',fontSize:Math.max(13, cx(13)),fontWeight:'400'}}>-</Text>
</TouchableOpacity>
<Slider value={testValue} onValueChange={(value)=>{
console.log('滑动了'+value)
this.setState({
testValue:value
})
}
}
style={{width:'80%',height:cx(40)}}
minimumValue={0}
maximumValue={200}
stepValue={1}
minimumTrackTintColor={ActiveThemeColor}
thumbTintColor={ActiveThemeColor}
thumbStyle={{borderWidth:6,backgroundColor:'white',borderColor:ActiveThemeColor}}
/>
<TouchableOpacity style={{width:'5%',backgroundColor:ActiveFontColor,justifyContent:'center',alignItems:'center',borderRadius:cx(6)}}
onPress={()=>{
let value = testValue+10;
if(value>200){
value=200;
}
this.setState({
testValue:value
})
}}
>
<Text style={{color:'white',fontSize:Math.max(13, cx(13)),fontWeight:'400'}}>+</Text>
</TouchableOpacity>
</View>
</View>

</View>
),
onMaskPress:({close})=>{close()},
motionType:'none',
footer: <View style={{marginBottom:cx(10)}}></View>,
})

}

Re: RN Popup.custom自定义View中Slider滑动后无法更新到Text组件

Posted: 2025年 Jul 13日 20:35
by lshinylee

问题原因

这在 React 中是符合预期的现象,因为 Popup.custom 是一个静态方法,通常是在某个事件(比如点击按钮)发生时被调用,然后创建并渲染一个组件。这个组件在创建时接收到的children是当时传入的 React 元素,这些元素在创建时已经固定了(闭包了当时的 props 和 state)。之后,即使父组件的状态发生变化,这个已经渲染的对话框组件并不会自动接收到更新后的children,因为它并不是父组件渲染树的一部分,而是通过 Portal 或者直接挂载到其他 DOM 节点的方式独立存在的。

解决方案

方案 1:使用受控组件模式

Code: Select all

// 在父组件中维护弹出层的状态
function ParentComponent() {
  const [count, setCount] = useState(0);
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>打开弹窗</button>
      
      {open && (
        <Modal>
          <Content count={count} /> {/* 随父组件更新自动重渲染 */}
        </Modal>
      )}
    </>
  );
}

方案 2:状态提升 + 全局状态管理

将 Popup.custom 参数的 content 字段抽离成一个 Content 组件,Content 组件内部通过 Redux 或 context 之类的方案监听全局状态的变更。


Re: RN Popup.custom自定义View中Slider滑动后无法更新到Text组件

Posted: 2025年 Jul 14日 00:07
by feige2023

看懂了,谢谢大佬,明天我试一下。