基于所选配送方式显示自定义字段:WooCommerce区块结账页问题
解决WooCommerce区块式结账页面根据配送方式显示自定义字段的问题
你不需要用原生JavaScript实现,直接在现有的block.js文件中修改即可——因为WooCommerce的区块式结账基于WordPress的React组件体系,直接利用其提供的useSelect钩子就能获取配送方式信息,进而控制自定义字段的显示。
修改步骤与完整代码
以下是调整后的block.js代码,我添加了获取选中配送方式、控制字段显示的逻辑:
/** * External dependencies */ import { useEffect, useState, useCallback } from '@wordpress/element'; import { SelectControl, TextareaControl } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { debounce } from 'lodash'; /** * Internal dependencies */ import { options } from './options'; import { txt } from './text'; export const Block = ({ checkoutExtensionData, extensions }) => { const { setExtensionData } = checkoutExtensionData; const debouncedSetExtensionData = useCallback( debounce((namespace, key, value) => { setExtensionData(namespace, key, value); }, 1000), [setExtensionData] ); const terminalValidationErrorId = 'terminal'; const { setValidationErrors, clearValidationError } = useDispatch( 'wc/store/validation' ); const validationError = useSelect((select) => { const store = select('wc/store/validation'); return store.getValidationError(terminalValidationErrorId); }); // 获取当前选中的配送方式 const selectedShippingRate = useSelect((select) => { return select('wc/store/cart').getSelectedShippingRate(); }, []); const [selectedTerminal, setSelectedTerminal] = useState(''); // 控制自定义字段的显示状态 const [isFieldVisible, setIsFieldVisible] = useState(false); // 监听配送方式变化,切换字段显示状态 useEffect(() => { // 替换成你需要触发显示的配送方式ID,比如['local_pickup', 'flat_rate'] const targetShippingMethods = ['local_pickup']; if (selectedShippingRate && targetShippingMethods.includes(selectedShippingRate.method_id)) { setIsFieldVisible(true); } else { setIsFieldVisible(false); // 隐藏字段时清空已选值并清除验证 setSelectedTerminal(''); clearValidationError(terminalValidationErrorId); } }, [selectedShippingRate, clearValidationError]); /* Handle changing the select's value */ useEffect(() => { if (!isFieldVisible) return; setExtensionData( 'terminals', 'alternateShippingInstruction', selectedTerminal ); if (selectedTerminal !== '') { clearValidationError(terminalValidationErrorId); return; } if (selectedTerminal === '') { setValidationErrors({ [terminalValidationErrorId]: { message: txt.error_terminal, hidden: false } }); } }, [ setExtensionData, selectedTerminal, setValidationErrors, clearValidationError, isFieldVisible ]); return ( // 根据isFieldVisible决定是否渲染整个字段容器 isFieldVisible ? ( <div className="terminal_select_container"> <SelectControl label={txt.title_terminal} value={selectedTerminal} options={options} onChange={setSelectedTerminal} /> {(validationError?.hidden || selectedTerminal !== '') ? null : ( <div className="wc-block-components-validation-error terminal-error"> <span>{validationError?.message}</span> </div> )} </div> ) : null ); };
关键逻辑说明
- 获取配送方式:通过
useSelect钩子从wc/store/cart存储中读取getSelectedShippingRate(),拿到当前用户选中的配送方式对象,其中method_id是配送方式的唯一标识(比如自提的local_pickup、平邮的flat_rate)。 - 控制显示状态:通过
useState创建isFieldVisible状态,在监听配送方式变化的useEffect中,判断当前选中的配送方式是否在你指定的目标列表里,动态切换显示状态。 - 适配原有逻辑:在处理字段值变化的
useEffect中增加isFieldVisible依赖,确保只有字段显示时才执行数据存储和验证逻辑;同时在隐藏字段时清空已选值,避免无效数据提交。
你只需要把代码中的targetShippingMethods数组替换成你实际需要触发显示的配送方式ID即可。
内容的提问来源于stack exchange,提问作者markak
相关产品推荐
相关产品推荐

