2 added 460 characters in body
source | link
wd = WeightedData[Range[3], Differences[{0, ## & @@ reaction}]]; 

SeedRandom[1]
RandomChoice[wd] 

3

RandomChoice[wd, 5] 

{1,3,1,2,1}

Update: a shorter alternative using FirstPosition

SeedRandom[123]
FirstPosition[reaction - RandomReal[], _?Positive][[1]]

2

Note: This function uses a single random number while the alternative

FirstPosition[reaction, _?(#>RandomReal[]&)][[1]]

creates a new random number for every comparison until the condition is satisfied (as does the code in OP), and hence, it can give a different result

SeedRandom[123]
FirstPosition[reaction, _?(#>RandomReal[]&)][[1]]

3

wd = WeightedData[Range[3], Differences[{0, ## & @@ reaction}]]; 

SeedRandom[1]
RandomChoice[wd] 

3

RandomChoice[wd, 5] 

{1,3,1,2,1}

wd = WeightedData[Range[3], Differences[{0, ## & @@ reaction}]]; 

SeedRandom[1]
RandomChoice[wd] 

3

RandomChoice[wd, 5] 

{1,3,1,2,1}

Update: a shorter alternative using FirstPosition

SeedRandom[123]
FirstPosition[reaction - RandomReal[], _?Positive][[1]]

2

Note: This function uses a single random number while the alternative

FirstPosition[reaction, _?(#>RandomReal[]&)][[1]]

creates a new random number for every comparison until the condition is satisfied (as does the code in OP), and hence, it can give a different result

SeedRandom[123]
FirstPosition[reaction, _?(#>RandomReal[]&)][[1]]

3

1
source | link

wd = WeightedData[Range[3], Differences[{0, ## & @@ reaction}]]; 

SeedRandom[1]
RandomChoice[wd] 

3

RandomChoice[wd, 5] 

{1,3,1,2,1}